From 6e2a232e562b7d432d26c335c8f7dbaa51734f76 Mon Sep 17 00:00:00 2001 From: dumerrill Date: Sat, 9 Mar 2013 05:00:35 -0500 Subject: [PATCH] - Fix for ambiguity in BlockScan::Reduce() between generic reduction and summation. Summation entrypoints are now called ::Sum(), similar to the convention in BlockScan. - Small edits to mainpage documentation and download tracking - Refactor test and docs outside of cub directory. Take generated html docs off gitignore. Former-commit-id: 98c1a6bc692d9659accc43b458cd5eb4cf7881f9 --- VERSION.TXT | 18 +- cub/block/block_reduce.cuh | 116 +- cub/cub.cuh | 393 ----- {cub/docs => docs}/.gitignore | 1 - {cub/docs => docs}/Doxyfile | 26 +- {cub/docs => docs}/DoxygenLayout.xml | 0 docs/download_cub.html | 51 + {cub/docs => docs}/extra_stylesheet.css | 0 {cub/docs => docs}/footer.html | 0 {cub/docs => docs}/header.html | 0 docs/html/annotated.html | 171 ++ docs/html/bc_s.png | Bin 0 -> 676 bytes docs/html/bdwn.png | Bin 0 -> 147 bytes docs/html/block__discontinuity_8cuh.html | 136 ++ docs/html/block__exchange_8cuh.html | 135 ++ docs/html/block__load_8cuh.html | 210 +++ docs/html/block__radix__sort_8cuh.html | 136 ++ docs/html/block__reduce_8cuh.html | 138 ++ docs/html/block__scan_8cuh.html | 147 ++ docs/html/block__store_8cuh.html | 193 +++ .../images => docs/html}/block_load_logo.png | Bin .../images => docs/html}/block_reduce.png | Bin .../html}/block_scan_raking.png | Bin .../html}/block_scan_warpscans.png | Bin .../images => docs/html}/block_store_logo.png | Bin {cub/docs/images => docs/html}/blocked.png | Bin docs/html/citelist.html | 110 ++ ...sscub_1_1_block_discontinuity-members.html | 124 ++ .../classcub_1_1_block_discontinuity.html | 548 +++++++ .../classcub_1_1_block_exchange-members.html | 124 ++ docs/html/classcub_1_1_block_exchange.html | 386 +++++ .../html/classcub_1_1_block_load-members.html | 122 ++ docs/html/classcub_1_1_block_load.html | 338 ++++ ...classcub_1_1_block_radix_sort-members.html | 126 ++ docs/html/classcub_1_1_block_radix_sort.html | 629 ++++++++ .../classcub_1_1_block_reduce-members.html | 126 ++ docs/html/classcub_1_1_block_reduce.html | 601 +++++++ .../html/classcub_1_1_block_scan-members.html | 150 ++ ...lasscub_1_1_block_scan.html.REMOVED.git-id | 1 + .../classcub_1_1_block_store-members.html | 122 ++ docs/html/classcub_1_1_block_store.html | 342 ++++ docs/html/classcub_1_1_warp_scan-members.html | 135 ++ docs/html/classcub_1_1_warp_scan.html | 1430 +++++++++++++++++ docs/html/classes.html | 138 ++ docs/html/closed.png | Bin 0 -> 132 bytes .../images => docs/html}/cub_overview.png | Bin docs/html/debug_8cuh.html | 177 ++ .../html}/devfun_abstraction.png | Bin .../dir_011e1c944d88f71be72e1e24a5fda7cf.html | 126 ++ .../dir_bb50a5ef59f19d030d06415663184d05.html | 116 ++ .../dir_cb3a671affffe7eeb3fdf5ae58e42cc8.html | 114 ++ .../dir_d583f216f1aafe19404e836b0c097ad2.html | 127 ++ .../images => docs/html}/discont_logo.png | Bin .../images => docs/html}/download-icon.png | Bin docs/html/download_cub.html | 51 + docs/html/doxygen.css | 1184 ++++++++++++++ docs/html/doxygen.png | Bin 0 -> 3779 bytes docs/html/dynsections.js | 97 ++ docs/html/extra_stylesheet.css | 410 +++++ {cub/docs/images => docs/html}/favicon.ico | Bin {cub/docs/images => docs/html}/favicon.png | Bin docs/html/ftv2blank.png | Bin 0 -> 86 bytes docs/html/ftv2cl.png | Bin 0 -> 453 bytes docs/html/ftv2doc.png | Bin 0 -> 746 bytes docs/html/ftv2folderclosed.png | Bin 0 -> 616 bytes docs/html/ftv2folderopen.png | Bin 0 -> 597 bytes docs/html/ftv2lastnode.png | Bin 0 -> 86 bytes docs/html/ftv2link.png | Bin 0 -> 746 bytes docs/html/ftv2mlastnode.png | Bin 0 -> 246 bytes docs/html/ftv2mnode.png | Bin 0 -> 246 bytes docs/html/ftv2mo.png | Bin 0 -> 403 bytes docs/html/ftv2node.png | Bin 0 -> 86 bytes docs/html/ftv2ns.png | Bin 0 -> 388 bytes docs/html/ftv2plastnode.png | Bin 0 -> 229 bytes docs/html/ftv2pnode.png | Bin 0 -> 229 bytes docs/html/ftv2splitbar.png | Bin 0 -> 314 bytes docs/html/ftv2vertline.png | Bin 0 -> 86 bytes docs/html/functions.html | 267 +++ docs/html/functions_func.html | 231 +++ docs/html/functions_type.html | 133 ++ docs/html/functions_vars.html | 124 ++ ...-icon-747d8b799a48162434b2c0595ba1317e.png | Bin docs/html/group___host_util.html | 195 +++ docs/html/group___simt.html | 114 ++ docs/html/group___simt_coop.html | 174 ++ .../group___simt_utils.html.REMOVED.git-id | 1 + .../docs/images => docs/html}/groups-icon.png | Bin docs/html/hierarchy.html | 173 ++ docs/html/index.html | 358 +++++ docs/html/jquery.js | 8 + .../html}/kernel_abstraction.png | Bin .../images => docs/html}/kogge_stone_scan.png | Bin docs/html/modules.html | 112 ++ docs/html/namespacecub.html | 547 +++++++ docs/html/nav_f.png | Bin 0 -> 153 bytes docs/html/nav_g.png | Bin 0 -> 95 bytes docs/html/nav_h.png | Bin 0 -> 98 bytes docs/html/open.png | Bin 0 -> 123 bytes docs/html/operators_8cuh.html | 134 ++ {cub/docs/images => docs/html}/raking.png | Bin .../docs/images => docs/html}/reduce_logo.png | Bin {cub/docs/images => docs/html}/scan_logo.png | Bin docs/html/search/all_61.html | 26 + docs/html/search/all_61.js | 4 + docs/html/search/all_62.html | 26 + docs/html/search/all_62.js | 39 + docs/html/search/all_63.html | 26 + docs/html/search/all_63.js | 9 + docs/html/search/all_64.html | 26 + docs/html/search/all_64.js | 5 + docs/html/search/all_65.html | 26 + docs/html/search/all_65.js | 8 + docs/html/search/all_66.html | 26 + docs/html/search/all_66.js | 4 + docs/html/search/all_68.html | 26 + docs/html/search/all_68.js | 4 + docs/html/search/all_69.html | 26 + docs/html/search/all_69.js | 7 + docs/html/search/all_6c.html | 26 + docs/html/search/all_6c.js | 5 + docs/html/search/all_6d.html | 26 + docs/html/search/all_6d.js | 4 + docs/html/search/all_6e.html | 26 + docs/html/search/all_6e.js | 6 + docs/html/search/all_6f.html | 26 + docs/html/search/all_6f.js | 5 + docs/html/search/all_70.html | 26 + docs/html/search/all_70.js | 18 + docs/html/search/all_72.html | 26 + docs/html/search/all_72.js | 5 + docs/html/search/all_73.html | 26 + docs/html/search/all_73.js | 15 + docs/html/search/all_74.html | 26 + docs/html/search/all_74.js | 10 + docs/html/search/all_76.html | 26 + docs/html/search/all_76.js | 4 + docs/html/search/all_77.html | 26 + docs/html/search/all_77.js | 5 + docs/html/search/classes_61.html | 26 + docs/html/search/classes_61.js | 4 + docs/html/search/classes_62.html | 26 + docs/html/search/classes_62.js | 13 + docs/html/search/classes_65.html | 26 + docs/html/search/classes_65.js | 6 + docs/html/search/classes_69.html | 26 + docs/html/search/classes_69.js | 5 + docs/html/search/classes_6c.html | 26 + docs/html/search/classes_6c.js | 4 + docs/html/search/classes_6d.html | 26 + docs/html/search/classes_6d.js | 4 + docs/html/search/classes_6e.html | 26 + docs/html/search/classes_6e.js | 6 + docs/html/search/classes_72.html | 26 + docs/html/search/classes_72.js | 4 + docs/html/search/classes_73.html | 26 + docs/html/search/classes_73.js | 4 + docs/html/search/classes_74.html | 26 + docs/html/search/classes_74.js | 4 + docs/html/search/classes_77.html | 26 + docs/html/search/classes_77.js | 4 + docs/html/search/close.png | Bin 0 -> 273 bytes docs/html/search/defines_63.html | 26 + docs/html/search/defines_63.js | 6 + docs/html/search/enums_62.html | 26 + docs/html/search/enums_62.js | 6 + docs/html/search/enums_63.html | 26 + docs/html/search/enums_63.js | 4 + docs/html/search/enums_70.html | 26 + docs/html/search/enums_70.js | 5 + docs/html/search/enumvalues_62.html | 26 + docs/html/search/enumvalues_62.js | 11 + docs/html/search/enumvalues_70.html | 26 + docs/html/search/enumvalues_70.js | 16 + docs/html/search/files_62.html | 26 + docs/html/search/files_62.js | 10 + docs/html/search/files_64.html | 26 + docs/html/search/files_64.js | 4 + docs/html/search/files_6f.html | 26 + docs/html/search/files_6f.js | 4 + docs/html/search/files_74.html | 26 + docs/html/search/files_74.js | 6 + docs/html/search/files_77.html | 26 + docs/html/search/files_77.js | 4 + docs/html/search/functions_62.html | 26 + docs/html/search/functions_62.js | 10 + docs/html/search/functions_64.html | 26 + docs/html/search/functions_64.js | 4 + docs/html/search/functions_65.html | 26 + docs/html/search/functions_65.js | 5 + docs/html/search/functions_66.html | 26 + docs/html/search/functions_66.js | 4 + docs/html/search/functions_69.html | 26 + docs/html/search/functions_69.js | 5 + docs/html/search/functions_6c.html | 26 + docs/html/search/functions_6c.js | 4 + docs/html/search/functions_6f.html | 26 + docs/html/search/functions_6f.js | 4 + docs/html/search/functions_72.html | 26 + docs/html/search/functions_72.js | 4 + docs/html/search/functions_73.html | 26 + docs/html/search/functions_73.js | 11 + docs/html/search/functions_74.html | 26 + docs/html/search/functions_74.js | 5 + docs/html/search/groups_63.html | 26 + docs/html/search/groups_63.js | 4 + docs/html/search/groups_68.html | 26 + docs/html/search/groups_68.js | 4 + docs/html/search/groups_73.html | 26 + docs/html/search/groups_73.js | 5 + docs/html/search/mag_sel.png | Bin 0 -> 563 bytes docs/html/search/namespaces_63.html | 26 + docs/html/search/namespaces_63.js | 4 + docs/html/search/nomatches.html | 12 + docs/html/search/pages_62.html | 26 + docs/html/search/pages_62.js | 4 + docs/html/search/search.css | 271 ++++ docs/html/search/search.js | 817 ++++++++++ docs/html/search/search_l.png | Bin 0 -> 604 bytes docs/html/search/search_m.png | Bin 0 -> 158 bytes docs/html/search/search_r.png | Bin 0 -> 612 bytes docs/html/search/typedefs_73.html | 26 + docs/html/search/typedefs_73.js | 4 + docs/html/search/typedefs_74.html | 26 + docs/html/search/typedefs_74.js | 4 + docs/html/search/variables_63.html | 26 + docs/html/search/variables_63.js | 4 + docs/html/search/variables_76.html | 26 + docs/html/search/variables_76.js | 4 + .../images => docs/html}/simt_abstraction.png | Bin .../images => docs/html}/sorting_logo.png | Bin {cub/docs/images => docs/html}/striped.png | Bin docs/html/structcub_1_1_array_traits.html | 124 ++ .../structcub_1_1_base_traits-members.html | 122 ++ docs/html/structcub_1_1_base_traits.html | 143 ++ .../html/structcub_1_1_enable_if-members.html | 120 ++ docs/html/structcub_1_1_enable_if.html | 135 ++ docs/html/structcub_1_1_equality-members.html | 120 ++ docs/html/structcub_1_1_equality.html | 136 ++ docs/html/structcub_1_1_equals-members.html | 121 ++ docs/html/structcub_1_1_equals.html | 135 ++ docs/html/structcub_1_1_if-members.html | 120 ++ docs/html/structcub_1_1_if.html | 135 ++ .../structcub_1_1_is_volatile-members.html | 120 ++ docs/html/structcub_1_1_is_volatile.html | 134 ++ docs/html/structcub_1_1_log2-members.html | 120 ++ docs/html/structcub_1_1_log2.html | 136 ++ docs/html/structcub_1_1_max-members.html | 120 ++ docs/html/structcub_1_1_max.html | 136 ++ docs/html/structcub_1_1_null_type.html | 121 ++ .../structcub_1_1_numeric_traits-members.html | 122 ++ docs/html/structcub_1_1_numeric_traits.html | 147 ++ docs/html/structcub_1_1_numeric_traits.png | Bin 0 -> 968 bytes ...ructcub_1_1_remove_qualifiers-members.html | 120 ++ .../html/structcub_1_1_remove_qualifiers.html | 136 ++ docs/html/structcub_1_1_sum-members.html | 120 ++ docs/html/structcub_1_1_sum.html | 136 ++ docs/html/structcub_1_1_traits-members.html | 122 ++ docs/html/structcub_1_1_traits.html | 148 ++ docs/html/structcub_1_1_traits.png | Bin 0 -> 1763 bytes docs/html/sync_off.png | Bin 0 -> 853 bytes docs/html/sync_on.png | Bin 0 -> 845 bytes docs/html/tab_a.png | Bin 0 -> 142 bytes docs/html/tab_b.png | Bin 0 -> 169 bytes {cub/docs/images => docs/html}/tab_b_alt.png | Bin docs/html/tab_h.png | Bin 0 -> 177 bytes docs/html/tab_s.png | Bin 0 -> 184 bytes docs/html/tabs.css | 60 + docs/html/thread__load_8cuh.html | 151 ++ docs/html/thread__store_8cuh.html | 147 ++ {cub/docs/images => docs/html}/tile.png | Bin .../images => docs/html}/transpose_logo.png | Bin docs/html/type__utils_8cuh.html | 215 +++ docs/html/warp__scan_8cuh.html | 137 ++ .../images => docs/html}/warp_scan_logo.png | Bin docs/images/block_load_logo.png | Bin 0 -> 10916 bytes docs/images/block_reduce.png | Bin 0 -> 35067 bytes docs/images/block_scan_raking.png | Bin 0 -> 62170 bytes docs/images/block_scan_warpscans.png | Bin 0 -> 79045 bytes docs/images/block_store_logo.png | Bin 0 -> 10733 bytes docs/images/blocked.png | Bin 0 -> 2412 bytes {cub/docs => docs}/images/cnp_abstraction.png | Bin {cub/docs => docs}/images/cub.png | Bin docs/images/cub_overview.png | Bin 0 -> 34776 bytes docs/images/devfun_abstraction.png | Bin 0 -> 34543 bytes docs/images/discont_logo.png | Bin 0 -> 3437 bytes docs/images/download-icon.png | Bin 0 -> 1699 bytes docs/images/favicon.ico | Bin 0 -> 1406 bytes docs/images/favicon.png | Bin 0 -> 437 bytes ...-icon-747d8b799a48162434b2c0595ba1317e.png | Bin 0 -> 2051 bytes docs/images/groups-icon.png | Bin 0 -> 1936 bytes docs/images/kernel_abstraction.png | Bin 0 -> 25548 bytes .../images/kogge_stone_reduction.png | Bin docs/images/kogge_stone_scan.png | Bin 0 -> 18407 bytes docs/images/raking.png | Bin 0 -> 14944 bytes docs/images/reduce_logo.png | Bin 0 -> 10611 bytes docs/images/scan_logo.png | Bin 0 -> 8452 bytes docs/images/simt_abstraction.png | Bin 0 -> 36651 bytes {cub/docs => docs}/images/sorting_logo.jpg | Bin docs/images/sorting_logo.png | Bin 0 -> 6690 bytes docs/images/striped.png | Bin 0 -> 2572 bytes docs/images/tab_b_alt.png | Bin 0 -> 196 bytes {cub/docs => docs}/images/thread_data_1.png | Bin docs/images/tile.png | Bin 0 -> 454 bytes docs/images/transpose_logo.png | Bin 0 -> 10786 bytes docs/images/warp_scan_logo.png | Bin 0 -> 3424 bytes docs/mainpage.dox | 423 +++++ {cub/docs => docs}/references.bib | 0 {cub/test => test}/.gitignore | 0 {cub/test => test}/Makefile | 0 {cub/test => test}/test_allocator.cu | 0 {cub/test => test}/test_block_load_store.cu | 0 {cub/test => test}/test_block_radix_sort.cu | 0 {cub/test => test}/test_block_reduce.cu | 108 +- {cub/test => test}/test_block_scan.cu | 0 {cub/test => test}/test_block_serialize.cu | 0 {cub/test => test}/test_coo_spmv.cu | 0 {cub/test => test}/test_coo_spmv_double.cu | 0 {cub/test => test}/test_grid_barrier.cu | 0 {cub/test => test}/test_util.h | 0 {cub/test => test}/test_warp_scan.cu | 0 320 files changed, 19524 insertions(+), 480 deletions(-) rename {cub/docs => docs}/.gitignore (70%) rename {cub/docs => docs}/Doxyfile (96%) rename {cub/docs => docs}/DoxygenLayout.xml (100%) create mode 100644 docs/download_cub.html rename {cub/docs => docs}/extra_stylesheet.css (100%) rename {cub/docs => docs}/footer.html (100%) rename {cub/docs => docs}/header.html (100%) create mode 100644 docs/html/annotated.html create mode 100644 docs/html/bc_s.png create mode 100644 docs/html/bdwn.png create mode 100644 docs/html/block__discontinuity_8cuh.html create mode 100644 docs/html/block__exchange_8cuh.html create mode 100644 docs/html/block__load_8cuh.html create mode 100644 docs/html/block__radix__sort_8cuh.html create mode 100644 docs/html/block__reduce_8cuh.html create mode 100644 docs/html/block__scan_8cuh.html create mode 100644 docs/html/block__store_8cuh.html rename {cub/docs/images => docs/html}/block_load_logo.png (100%) rename {cub/docs/images => docs/html}/block_reduce.png (100%) rename {cub/docs/images => docs/html}/block_scan_raking.png (100%) rename {cub/docs/images => docs/html}/block_scan_warpscans.png (100%) rename {cub/docs/images => docs/html}/block_store_logo.png (100%) rename {cub/docs/images => docs/html}/blocked.png (100%) create mode 100644 docs/html/citelist.html create mode 100644 docs/html/classcub_1_1_block_discontinuity-members.html create mode 100644 docs/html/classcub_1_1_block_discontinuity.html create mode 100644 docs/html/classcub_1_1_block_exchange-members.html create mode 100644 docs/html/classcub_1_1_block_exchange.html create mode 100644 docs/html/classcub_1_1_block_load-members.html create mode 100644 docs/html/classcub_1_1_block_load.html create mode 100644 docs/html/classcub_1_1_block_radix_sort-members.html create mode 100644 docs/html/classcub_1_1_block_radix_sort.html create mode 100644 docs/html/classcub_1_1_block_reduce-members.html create mode 100644 docs/html/classcub_1_1_block_reduce.html create mode 100644 docs/html/classcub_1_1_block_scan-members.html create mode 100644 docs/html/classcub_1_1_block_scan.html.REMOVED.git-id create mode 100644 docs/html/classcub_1_1_block_store-members.html create mode 100644 docs/html/classcub_1_1_block_store.html create mode 100644 docs/html/classcub_1_1_warp_scan-members.html create mode 100644 docs/html/classcub_1_1_warp_scan.html create mode 100644 docs/html/classes.html create mode 100644 docs/html/closed.png rename {cub/docs/images => docs/html}/cub_overview.png (100%) create mode 100644 docs/html/debug_8cuh.html rename {cub/docs/images => docs/html}/devfun_abstraction.png (100%) create mode 100644 docs/html/dir_011e1c944d88f71be72e1e24a5fda7cf.html create mode 100644 docs/html/dir_bb50a5ef59f19d030d06415663184d05.html create mode 100644 docs/html/dir_cb3a671affffe7eeb3fdf5ae58e42cc8.html create mode 100644 docs/html/dir_d583f216f1aafe19404e836b0c097ad2.html rename {cub/docs/images => docs/html}/discont_logo.png (100%) rename {cub/docs/images => docs/html}/download-icon.png (100%) create mode 100644 docs/html/download_cub.html create mode 100644 docs/html/doxygen.css create mode 100644 docs/html/doxygen.png create mode 100644 docs/html/dynsections.js create mode 100644 docs/html/extra_stylesheet.css rename {cub/docs/images => docs/html}/favicon.ico (100%) rename {cub/docs/images => docs/html}/favicon.png (100%) create mode 100644 docs/html/ftv2blank.png create mode 100644 docs/html/ftv2cl.png create mode 100644 docs/html/ftv2doc.png create mode 100644 docs/html/ftv2folderclosed.png create mode 100644 docs/html/ftv2folderopen.png create mode 100644 docs/html/ftv2lastnode.png create mode 100644 docs/html/ftv2link.png create mode 100644 docs/html/ftv2mlastnode.png create mode 100644 docs/html/ftv2mnode.png create mode 100644 docs/html/ftv2mo.png create mode 100644 docs/html/ftv2node.png create mode 100644 docs/html/ftv2ns.png create mode 100644 docs/html/ftv2plastnode.png create mode 100644 docs/html/ftv2pnode.png create mode 100644 docs/html/ftv2splitbar.png create mode 100644 docs/html/ftv2vertline.png create mode 100644 docs/html/functions.html create mode 100644 docs/html/functions_func.html create mode 100644 docs/html/functions_type.html create mode 100644 docs/html/functions_vars.html rename {cub/docs/images => docs/html}/github-icon-747d8b799a48162434b2c0595ba1317e.png (100%) create mode 100644 docs/html/group___host_util.html create mode 100644 docs/html/group___simt.html create mode 100644 docs/html/group___simt_coop.html create mode 100644 docs/html/group___simt_utils.html.REMOVED.git-id rename {cub/docs/images => docs/html}/groups-icon.png (100%) create mode 100644 docs/html/hierarchy.html create mode 100644 docs/html/index.html create mode 100644 docs/html/jquery.js rename {cub/docs/images => docs/html}/kernel_abstraction.png (100%) rename {cub/docs/images => docs/html}/kogge_stone_scan.png (100%) create mode 100644 docs/html/modules.html create mode 100644 docs/html/namespacecub.html create mode 100644 docs/html/nav_f.png create mode 100644 docs/html/nav_g.png create mode 100644 docs/html/nav_h.png create mode 100644 docs/html/open.png create mode 100644 docs/html/operators_8cuh.html rename {cub/docs/images => docs/html}/raking.png (100%) rename {cub/docs/images => docs/html}/reduce_logo.png (100%) rename {cub/docs/images => docs/html}/scan_logo.png (100%) create mode 100644 docs/html/search/all_61.html create mode 100644 docs/html/search/all_61.js create mode 100644 docs/html/search/all_62.html create mode 100644 docs/html/search/all_62.js create mode 100644 docs/html/search/all_63.html create mode 100644 docs/html/search/all_63.js create mode 100644 docs/html/search/all_64.html create mode 100644 docs/html/search/all_64.js create mode 100644 docs/html/search/all_65.html create mode 100644 docs/html/search/all_65.js create mode 100644 docs/html/search/all_66.html create mode 100644 docs/html/search/all_66.js create mode 100644 docs/html/search/all_68.html create mode 100644 docs/html/search/all_68.js create mode 100644 docs/html/search/all_69.html create mode 100644 docs/html/search/all_69.js create mode 100644 docs/html/search/all_6c.html create mode 100644 docs/html/search/all_6c.js create mode 100644 docs/html/search/all_6d.html create mode 100644 docs/html/search/all_6d.js create mode 100644 docs/html/search/all_6e.html create mode 100644 docs/html/search/all_6e.js create mode 100644 docs/html/search/all_6f.html create mode 100644 docs/html/search/all_6f.js create mode 100644 docs/html/search/all_70.html create mode 100644 docs/html/search/all_70.js create mode 100644 docs/html/search/all_72.html create mode 100644 docs/html/search/all_72.js create mode 100644 docs/html/search/all_73.html create mode 100644 docs/html/search/all_73.js create mode 100644 docs/html/search/all_74.html create mode 100644 docs/html/search/all_74.js create mode 100644 docs/html/search/all_76.html create mode 100644 docs/html/search/all_76.js create mode 100644 docs/html/search/all_77.html create mode 100644 docs/html/search/all_77.js create mode 100644 docs/html/search/classes_61.html create mode 100644 docs/html/search/classes_61.js create mode 100644 docs/html/search/classes_62.html create mode 100644 docs/html/search/classes_62.js create mode 100644 docs/html/search/classes_65.html create mode 100644 docs/html/search/classes_65.js create mode 100644 docs/html/search/classes_69.html create mode 100644 docs/html/search/classes_69.js create mode 100644 docs/html/search/classes_6c.html create mode 100644 docs/html/search/classes_6c.js create mode 100644 docs/html/search/classes_6d.html create mode 100644 docs/html/search/classes_6d.js create mode 100644 docs/html/search/classes_6e.html create mode 100644 docs/html/search/classes_6e.js create mode 100644 docs/html/search/classes_72.html create mode 100644 docs/html/search/classes_72.js create mode 100644 docs/html/search/classes_73.html create mode 100644 docs/html/search/classes_73.js create mode 100644 docs/html/search/classes_74.html create mode 100644 docs/html/search/classes_74.js create mode 100644 docs/html/search/classes_77.html create mode 100644 docs/html/search/classes_77.js create mode 100644 docs/html/search/close.png create mode 100644 docs/html/search/defines_63.html create mode 100644 docs/html/search/defines_63.js create mode 100644 docs/html/search/enums_62.html create mode 100644 docs/html/search/enums_62.js create mode 100644 docs/html/search/enums_63.html create mode 100644 docs/html/search/enums_63.js create mode 100644 docs/html/search/enums_70.html create mode 100644 docs/html/search/enums_70.js create mode 100644 docs/html/search/enumvalues_62.html create mode 100644 docs/html/search/enumvalues_62.js create mode 100644 docs/html/search/enumvalues_70.html create mode 100644 docs/html/search/enumvalues_70.js create mode 100644 docs/html/search/files_62.html create mode 100644 docs/html/search/files_62.js create mode 100644 docs/html/search/files_64.html create mode 100644 docs/html/search/files_64.js create mode 100644 docs/html/search/files_6f.html create mode 100644 docs/html/search/files_6f.js create mode 100644 docs/html/search/files_74.html create mode 100644 docs/html/search/files_74.js create mode 100644 docs/html/search/files_77.html create mode 100644 docs/html/search/files_77.js create mode 100644 docs/html/search/functions_62.html create mode 100644 docs/html/search/functions_62.js create mode 100644 docs/html/search/functions_64.html create mode 100644 docs/html/search/functions_64.js create mode 100644 docs/html/search/functions_65.html create mode 100644 docs/html/search/functions_65.js create mode 100644 docs/html/search/functions_66.html create mode 100644 docs/html/search/functions_66.js create mode 100644 docs/html/search/functions_69.html create mode 100644 docs/html/search/functions_69.js create mode 100644 docs/html/search/functions_6c.html create mode 100644 docs/html/search/functions_6c.js create mode 100644 docs/html/search/functions_6f.html create mode 100644 docs/html/search/functions_6f.js create mode 100644 docs/html/search/functions_72.html create mode 100644 docs/html/search/functions_72.js create mode 100644 docs/html/search/functions_73.html create mode 100644 docs/html/search/functions_73.js create mode 100644 docs/html/search/functions_74.html create mode 100644 docs/html/search/functions_74.js create mode 100644 docs/html/search/groups_63.html create mode 100644 docs/html/search/groups_63.js create mode 100644 docs/html/search/groups_68.html create mode 100644 docs/html/search/groups_68.js create mode 100644 docs/html/search/groups_73.html create mode 100644 docs/html/search/groups_73.js create mode 100644 docs/html/search/mag_sel.png create mode 100644 docs/html/search/namespaces_63.html create mode 100644 docs/html/search/namespaces_63.js create mode 100644 docs/html/search/nomatches.html create mode 100644 docs/html/search/pages_62.html create mode 100644 docs/html/search/pages_62.js create mode 100644 docs/html/search/search.css create mode 100644 docs/html/search/search.js create mode 100644 docs/html/search/search_l.png create mode 100644 docs/html/search/search_m.png create mode 100644 docs/html/search/search_r.png create mode 100644 docs/html/search/typedefs_73.html create mode 100644 docs/html/search/typedefs_73.js create mode 100644 docs/html/search/typedefs_74.html create mode 100644 docs/html/search/typedefs_74.js create mode 100644 docs/html/search/variables_63.html create mode 100644 docs/html/search/variables_63.js create mode 100644 docs/html/search/variables_76.html create mode 100644 docs/html/search/variables_76.js rename {cub/docs/images => docs/html}/simt_abstraction.png (100%) rename {cub/docs/images => docs/html}/sorting_logo.png (100%) rename {cub/docs/images => docs/html}/striped.png (100%) create mode 100644 docs/html/structcub_1_1_array_traits.html create mode 100644 docs/html/structcub_1_1_base_traits-members.html create mode 100644 docs/html/structcub_1_1_base_traits.html create mode 100644 docs/html/structcub_1_1_enable_if-members.html create mode 100644 docs/html/structcub_1_1_enable_if.html create mode 100644 docs/html/structcub_1_1_equality-members.html create mode 100644 docs/html/structcub_1_1_equality.html create mode 100644 docs/html/structcub_1_1_equals-members.html create mode 100644 docs/html/structcub_1_1_equals.html create mode 100644 docs/html/structcub_1_1_if-members.html create mode 100644 docs/html/structcub_1_1_if.html create mode 100644 docs/html/structcub_1_1_is_volatile-members.html create mode 100644 docs/html/structcub_1_1_is_volatile.html create mode 100644 docs/html/structcub_1_1_log2-members.html create mode 100644 docs/html/structcub_1_1_log2.html create mode 100644 docs/html/structcub_1_1_max-members.html create mode 100644 docs/html/structcub_1_1_max.html create mode 100644 docs/html/structcub_1_1_null_type.html create mode 100644 docs/html/structcub_1_1_numeric_traits-members.html create mode 100644 docs/html/structcub_1_1_numeric_traits.html create mode 100644 docs/html/structcub_1_1_numeric_traits.png create mode 100644 docs/html/structcub_1_1_remove_qualifiers-members.html create mode 100644 docs/html/structcub_1_1_remove_qualifiers.html create mode 100644 docs/html/structcub_1_1_sum-members.html create mode 100644 docs/html/structcub_1_1_sum.html create mode 100644 docs/html/structcub_1_1_traits-members.html create mode 100644 docs/html/structcub_1_1_traits.html create mode 100644 docs/html/structcub_1_1_traits.png create mode 100644 docs/html/sync_off.png create mode 100644 docs/html/sync_on.png create mode 100644 docs/html/tab_a.png create mode 100644 docs/html/tab_b.png rename {cub/docs/images => docs/html}/tab_b_alt.png (100%) create mode 100644 docs/html/tab_h.png create mode 100644 docs/html/tab_s.png create mode 100644 docs/html/tabs.css create mode 100644 docs/html/thread__load_8cuh.html create mode 100644 docs/html/thread__store_8cuh.html rename {cub/docs/images => docs/html}/tile.png (100%) rename {cub/docs/images => docs/html}/transpose_logo.png (100%) create mode 100644 docs/html/type__utils_8cuh.html create mode 100644 docs/html/warp__scan_8cuh.html rename {cub/docs/images => docs/html}/warp_scan_logo.png (100%) create mode 100644 docs/images/block_load_logo.png create mode 100644 docs/images/block_reduce.png create mode 100644 docs/images/block_scan_raking.png create mode 100644 docs/images/block_scan_warpscans.png create mode 100644 docs/images/block_store_logo.png create mode 100644 docs/images/blocked.png rename {cub/docs => docs}/images/cnp_abstraction.png (100%) rename {cub/docs => docs}/images/cub.png (100%) create mode 100644 docs/images/cub_overview.png create mode 100644 docs/images/devfun_abstraction.png create mode 100644 docs/images/discont_logo.png create mode 100644 docs/images/download-icon.png create mode 100644 docs/images/favicon.ico create mode 100644 docs/images/favicon.png create mode 100644 docs/images/github-icon-747d8b799a48162434b2c0595ba1317e.png create mode 100644 docs/images/groups-icon.png create mode 100644 docs/images/kernel_abstraction.png rename {cub/docs => docs}/images/kogge_stone_reduction.png (100%) create mode 100644 docs/images/kogge_stone_scan.png create mode 100644 docs/images/raking.png create mode 100644 docs/images/reduce_logo.png create mode 100644 docs/images/scan_logo.png create mode 100644 docs/images/simt_abstraction.png rename {cub/docs => docs}/images/sorting_logo.jpg (100%) create mode 100644 docs/images/sorting_logo.png create mode 100644 docs/images/striped.png create mode 100644 docs/images/tab_b_alt.png rename {cub/docs => docs}/images/thread_data_1.png (100%) create mode 100644 docs/images/tile.png create mode 100644 docs/images/transpose_logo.png create mode 100644 docs/images/warp_scan_logo.png create mode 100644 docs/mainpage.dox rename {cub/docs => docs}/references.bib (100%) rename {cub/test => test}/.gitignore (100%) rename {cub/test => test}/Makefile (100%) rename {cub/test => test}/test_allocator.cu (100%) rename {cub/test => test}/test_block_load_store.cu (100%) rename {cub/test => test}/test_block_radix_sort.cu (100%) rename {cub/test => test}/test_block_reduce.cu (81%) rename {cub/test => test}/test_block_scan.cu (100%) rename {cub/test => test}/test_block_serialize.cu (100%) rename {cub/test => test}/test_coo_spmv.cu (100%) rename {cub/test => test}/test_coo_spmv_double.cu (100%) rename {cub/test => test}/test_grid_barrier.cu (100%) rename {cub/test => test}/test_util.h (100%) rename {cub/test => test}/test_warp_scan.cu (100%) diff --git a/VERSION.TXT b/VERSION.TXT index 031c0f5ac3..a5a13377dd 100644 --- a/VERSION.TXT +++ b/VERSION.TXT @@ -1 +1,17 @@ -CUB version 0.900 + +0.9.1 03/09/2013 + + - Fix for ambiguity in BlockScan::Reduce() between generic reduction and + summation. Summation entrypoints are now called ::Sum(), similar + to the convention in BlockScan. + + - Small edits to mainpage documentation and download tracking + +//----------------------------------------------------------------------------- + +0.9.0 03/07/2013 + + - Intial "preview" release. CUB is the first durable, high-performance library + of cooperative block-level, warp-level, and thread-level primitives for CUDA + kernel programming. More primitives and examples coming soon! + \ No newline at end of file diff --git a/cub/block/block_reduce.cuh b/cub/block/block_reduce.cuh index 4a4b0f493f..b158bceb18 100644 --- a/cub/block/block_reduce.cuh +++ b/cub/block/block_reduce.cuh @@ -112,7 +112,7 @@ namespace cub { * ... * * // Compute the threadblock-wide sum for thread0 - * int aggregate = BlockReduce::Reduce(smem_storage, data); + * int aggregate = BlockReduce::Sum(smem_storage, data); * * ... * \endcode @@ -137,7 +137,7 @@ namespace cub { * if (threadIdx.x < num_elements) data = ...; * * // Compute the threadblock-wide sum of valid elements in thread0 - * int aggregate = BlockReduce::Reduce(smem_storage, data, num_elements); + * int aggregate = BlockReduce::Sum(smem_storage, data, num_elements); * * ... * \endcode @@ -296,63 +296,7 @@ private: public: - /******************************************************************//** - * \name Summation reductions - *********************************************************************/ - //@{ - - /** - * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes one input element. - * - * The return value is undefined in threads other than thread0. - * - * \smemreuse - */ - static __device__ __forceinline__ T Reduce( - SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout - T input) ///< [in] Calling thread's input - { - Sum reduction_op; - return Reduce(smem_storage, input, reduction_op); - } - - /** - * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes an array of consecutive input elements. - * - * The return value is undefined in threads other than thread0. - * - * \smemreuse - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ - template - static __device__ __forceinline__ T Reduce( - SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout - T (&inputs)[ITEMS_PER_THREAD]) ///< [in] Calling thread's input segment - { - Sum reduction_op; - return Reduce(smem_storage, inputs, reduction_op); - } - - - /** - * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. The first \p valid_threads threads each contribute one input element. - * - * \smemreuse - * - * The return value is undefined in threads other than thread0. - */ - static __device__ __forceinline__ T Reduce( - SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout - T input, ///< [in] Calling thread's input - const unsigned int &valid_threads) ///< [in] Number of threads containing valid elements (may be less than BLOCK_THREADS) - { - Sum reduction_op; - return Reduce(smem_storage, input, valid_threads); - } - - //@} /******************************************************************//** * \name Generic reductions *********************************************************************/ @@ -430,7 +374,63 @@ public: } //@} + /******************************************************************//** + * \name Summation reductions + *********************************************************************/ + //@{ + + /** + * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes one input element. + * + * The return value is undefined in threads other than thread0. + * + * \smemreuse + */ + static __device__ __forceinline__ T Sum( + SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout + T input) ///< [in] Calling thread's input + { + cub::Sum reduction_op; + return Reduce(smem_storage, input, reduction_op); + } + + /** + * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes an array of consecutive input elements. + * + * The return value is undefined in threads other than thread0. + * + * \smemreuse + * + * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. + */ + template + static __device__ __forceinline__ T Sum( + SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout + T (&inputs)[ITEMS_PER_THREAD]) ///< [in] Calling thread's input segment + { + cub::Sum reduction_op; + return Reduce(smem_storage, inputs, reduction_op); + } + + /** + * \brief Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. The first \p valid_threads threads each contribute one input element. + * + * \smemreuse + * + * The return value is undefined in threads other than thread0. + */ + static __device__ __forceinline__ T Sum( + SmemStorage &smem_storage, ///< [in] Shared reference to opaque SmemStorage layout + T input, ///< [in] Calling thread's input + const unsigned int &valid_threads) ///< [in] Number of threads containing valid elements (may be less than BLOCK_THREADS) + { + cub::Sum reduction_op; + return Reduce(smem_storage, input, reduction_op, valid_threads); + } + + + //@} }; /** @} */ // end of SimtCoop group diff --git a/cub/cub.cuh b/cub/cub.cuh index 1e02cdc5b2..a047a76ecb 100644 --- a/cub/cub.cuh +++ b/cub/cub.cuh @@ -72,396 +72,3 @@ #include "vector_type.cuh" #include "allocator.cuh" - -/** - * \mainpage - * - * \tableofcontents - * - * \htmlonly - * - *    - * Download CUB! - *
- * - *    - * Browse or fork CUB at GitHub! - *
- * - *    - * Join the cub-users discussion forum! - * \endhtmlonly - * - * \section sec0 (1) What is CUB? - * - * \par - * CUB is a library of high-performance parallel primitives and other utilities for - * constructing CUDA kernel software. CUB enhances productivity, performance, and portability - * by providing an abstraction layer over complex - * [block-level] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#programming-model), - * [warp-level] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#hardware-implementation), and - * [thread-level](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#programming-model) operations. - * - * \par - * CUB's primitives are not bound to any particular width of parallelism or to any particular - * data type. This allows them to be flexible and tunable to fit your kernels' needs. - * Thus CUB is [CUDA Unbound](index.html). - * - * \image html cub_overview.png - * - * \par - * Browse our collections of: - * - [Cooperative primitives](group___simt_coop.html), including: - * - Thread block operations (e.g., radix sort, prefix scan, reduction, etc.) - * - Warp operations (e.g., prefix scan) - * - [SIMT utilities](group___simt_utils.html), including: - * - Tile-based I/O utilities (e.g., for performing {vectorized, coalesced} data movement of {blocked, striped} data tiles) - * - Low-level thread I/O using cache-modifiers - * - Abstractions for thread block work distribution (e.g., work-stealing, even-share, etc.) - * - [Host utilities](group___host_util.html), including: - * - Caching allocator for quick management of device temporaries - * - Device reflection - * - * \section sec2 (2) Recent news - * - * \par - * - [CUB v0.9 "preview" release](https://github.com/NVlabs/cub/archive/0.9.zip) (3/7/2013). CUB is the first durable, high-performance - * library of cooperative block-level, warp-level, and thread-level primitives for CUDA kernel - * programming. More primitives and examples coming soon! - * - * \section sec3 (3) A simple example - * - * \par - * The following code snippet illustrates a simple CUDA kernel for sorting a thread block's data: - * - * \par - * \code - * #include - * - * // An tile-sorting CUDA kernel - * template < - * int BLOCK_THREADS, // Threads per block - * int ITEMS_PER_THREAD, // Items per thread - * typename T> // Numeric data type - * __global__ void TileSortKernel(T *d_in, T *d_out) - * { - * using namespace cub; - * const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - * - * // Parameterize cub::BlockRadixSort for the parallel execution context - * typedef BlockRadixSort BlockRadixSort; - * - * // Declare the shared memory needed by BlockRadixSort - * __shared__ typename BlockRadixSort::SmemStorage smem_storage; - * - * // A segment of data items per thread - * T data[ITEMS_PER_THREAD]; - * - * // Load a tile of data using vector-load instructions - * BlockLoadVectorized(data, d_in + (blockIdx.x * TILE_SIZE)); - * - * // Sort data in ascending order - * BlockRadixSort::SortBlocked(smem_storage, data); - * - * // Store the sorted tile using vector-store instructions - * BlockStoreVectorized(data, d_out + (blockIdx.x * TILE_SIZE)); - * } - * \endcode - * - * \par - * The cub::BlockRadixSort type performs a cooperative radix sort across the - * thread block's data items. Its implementation is parameterized by the number of threads per block and the aggregate - * data type \p T and is specialized for the underlying architecture. - * - * \par - * Once instantiated, the cub::BlockRadixSort type exposes an opaque cub::BlockRadixSort::SmemStorage - * member type. The thread block uses this storage type to allocate the shared memory needed by the - * primitive. This storage type can be aliased or union'd with other types so that the - * shared memory can be reused for other purposes. - * - * \par - * Furthermore, the kernel uses CUB's primitives for vectorizing global - * loads and stores. For example, lower-level ld.global.v4.s32 - * [PTX instructions](http://docs.nvidia.com/cuda/parallel-thread-execution) - * will be generated when \p T = \p int and \p ITEMS_PER_THREAD is a multiple of 4. - * - * \section sec4 (4) Why do you need CUB? - * - * \par - * CUDA kernel software is where the complexity of parallelism is expressed. - * Programmers must reason about deadlock, livelock, synchronization, race conditions, - * shared memory layout, plurality of state, granularity, throughput, latency, - * memory bottlenecks, etc. Constructing and fine-tuning kernel code is perhaps the - * most challenging, time-consuming aspect of CUDA programming. - * - * \par - * However, with the exception of CUB, there are few (if any) software libraries of - * reusable kernel primitives. In the CUDA ecosystem, CUB is unique in this regard. - * As a [SIMT](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#hardware-implementation) - * library and software abstraction layer, CUB provides: - * -# Simplicity of composition. Parallel CUB primitives can be simply sequenced - * together in kernel code. (This convenience is analogous to programming with - * [Thrust](http://thrust.github.com/) primitives in the host program.) - * -# High performance. CUB simplifies high performance kernel development by - * taking care to implement and make available the fastest available algorithms, - * strategies, and techniques. - * -# Performance portability. CUB primitives are specialized to match - * the target hardware. Furthermore, the CUB library continually evolves to accommodate new - * algorithmic developments, hardware instructions, etc. - * -# Simplicity of performance tuning. CUB primitives provide parallel abstractions - * whose performance behavior can be statically tuned. For example, most CUB primitives - * support alternative algorithmic strategies and variable grain sizes (threads per block, - * items per thread, etc.). - * -# Robustness and durability. CUB primitives are designed to function properly for - * arbitrary data types and widths of parallelism (not just for the built-in C++ types - * or for powers-of-two threads per block). - * - * \section sec5 (5) Where is CUB positioned in the CUDA ecosystem? - * - * \par - * CUDA's programming model embodies three different levels of program execution, each - * engendering its own abstraction layer in the CUDA software stack (i.e., the "black boxes" - * below): - * - * - * - * - * - * - * - * - * - * - *
- * \par - * CUDA kernel. A single CPU thread invokes a CUDA kernel to perform - * some data-parallel function. The incorporation of entire kernels (and their - * corresponding invocation stubs) into libraries is the most common form of code reuse for - * CUDA. Libraries of CUDA kernels include the following: - * - [cuBLAS](https://developer.nvidia.com/cublas) - * - [cuFFT](https://developer.nvidia.com/cufft) - * - [cuSPARSE](https://developer.nvidia.com/cusparse) - * - [Thrust](http://thrust.github.com/) - * - * \htmlonly - * - * \endhtmlonly - *
- * \par - * Thread blocks (SIMT). Each kernel invocation comprises some number of parallel - * threads. Threads are grouped into blocks, and the entire block of threads invokes some cooperative - * function in which they communicate and synchronize with each other. There has historically been very - * little reuse of cooperative SIMT software within CUDA kernel. Libraries of thread-block primitives - * include the following: - * - [CUB](index.html) - * - * \htmlonly - * - * \endhtmlonly - *
- * \par - * CUDA thread. A single CUDA thread invokes some sequential function. - * This is the finest-grained level of CUDA software abstraction and requires - * no consideration for the scheduling or synchronization of parallel threads. CUDA libraries of - * purely data-parallel functions include the following: - * - [ CUDA Math](http://docs.nvidia.com/cuda/cuda-math-api/index.html), - * [Texture](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#texture-functions), and - * [Atomic](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions) APIs - * - [cuRAND](https://developer.nvidia.com/curand)'s device-code interface - * - [CUB](index.html) - * - * \htmlonly - * - * \endhtmlonly - *
- * - * - * \section sec6 (6) How does CUB work? - * - * \par - * CUB leverages the following programming idioms: - * -# [C++ templates](index.html#sec3sec1) - * -# [Reflective type structure](index.html#sec3sec2) - * -# [Flexible data mapping](index.html#sec3sec3) - * - * \subsection sec3sec1 6.1    C++ templates - * - * \par - * As a SIMT library, CUB must be flexible enough to accommodate a wide spectrum - * of parallel execution contexts, - * i.e., specific: - * - Data types - * - Widths of parallelism (threads per block) - * - Grain sizes (data items per thread) - * - Underlying architectures (special instructions, warp size, rules for bank conflicts, etc.) - * - Tuning requirements (e.g., latency vs. throughput) - * - * \par - * To provide this flexibility, CUB is implemented as a C++ template library. - * C++ templates are a way to write generic algorithms and data structures. - * There is no need to build CUB separately. You simply \#include the - * cub.cuh header file into your .cu CUDA C++ sources - * and compile with NVIDIA's nvcc compiler. - * - * \subsection sec3sec2 6.2    Reflective type structure - * - * \par - * Cooperation within a thread block requires shared memory for communicating between threads. - * However, the specific size and layout of the memory needed by a given - * primitive will be specific to the details of its parallel execution context (e.g., how - * many threads are calling into it, how many items are processed per thread, etc.). Furthermore, - * this shared memory must be allocated outside of the component itself if it is to be - * reused elsewhere by the thread block. - * - * \par - * \code - * // Parameterize a BlockScan type for use with 128 threads - * // and 4 items per thread - * typedef cub::BlockScan BlockScan; - * - * // Declare shared memory for BlockScan - * __shared__ typename BlockScan::SmemStorage smem_storage; - * - * // A segment of consecutive input items per thread - * int data[4]; - * - * // Obtain data in blocked order - * ... - * - * // Perform an exclusive prefix sum across the tile of data - * BlockScan::ExclusiveSum(smem_storage, data, data); - * - * \endcode - * - * \par - * To address this issue, we encapsulate cooperative procedures within - * reflective type structure (C++ classes). As illustrated in the - * cub::BlockScan example above, these primitives are C++ classes with - * interfaces that expose both: - * - Procedural entrypoints for a block of threads to invoke - * - An opaque shared memory type needed for the operation of those methods - * - * \subsection sec3sec3 6.3    Flexible data mapping - * - * \par - * We often design kernels such that each thread block is assigned a "tile" of data - * items for processing. - * - * \par - * \image html tile.png - *
Tile of eight ordered data items
- - * \par - * When the tile size equals the thread block size, the - * mapping of data onto threads is straightforward (one datum per thread). - * However, there are often performance advantages for processing more - * than one datum per thread. For these scenarios, CUB primitives - * support the following alternatives for partitioning data items across - * the block of threads: - * - * - * - * - * - * - * - * - *
- * \par - * - Blocked arrangement. The aggregate tile of items is partitioned - * evenly across threads in "blocked" fashion with threadi - * owning the ith segment of consecutive elements. - * Blocked arrangements are often desirable for algorithmic benefits (where - * long sequences of items can be processed sequentially within each thread). - * - * \par - * \image html blocked.png - *
Blocked arrangement across four threads
(emphasis on items owned by thread0)
- *
- * \par - * - Striped arrangement. The aggregate tile of items is partitioned across - * threads in "striped" fashion, i.e., the \p ITEMS_PER_THREAD items owned by - * each thread have logical stride \p BLOCK_THREADS between them. Striped arrangements - * are often desirable for data movement through global memory (where - * [read/write coalescing](http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#coalesced-access-global-memory) - * is an important performance consideration). - * - * \par - * \image html striped.png - *
Striped arrangement across four threads
(emphasis on items owned by thread0)
- *
- * - * \par - * The benefits of processing multiple items per thread (a.k.a., register blocking, granularity coarsening, etc.) include: - * - Algorithmic efficiency. Sequential work over multiple items in - * thread-private registers is cheaper than synchronized, cooperative - * work through shared memory spaces. - * - Data occupancy. The number of items that can be resident on-chip in - * thread-private register storage is often greater than the number of - * schedulable threads. - * - Instruction-level parallelism. Multiple items per thread also - * facilitates greater ILP for improved throughput and utilization. - * - * \par - * Finally, cub::BlockExchange provides operations for converting between blocked - * and striped arrangements. - * - * \section sec7 (7) Contributors - * - * \par - * CUB is developed as an open-source project by [NVIDIA Research](http://research.nvidia.com). - * The primary contributor is [Duane Merrill](http://github.com/dumerrill). - * - * \section sec8 (8) Open Source License - * - * \par - * CUB is available under the "New BSD" open-source license: - * - * \par - * \code - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * \endcode - * - */ - - -/** - * \defgroup Simt SIMT Primitives - */ - -/** - * \defgroup SimtCoop Cooperative SIMT Operations - * \ingroup Simt - */ - -/** - * \defgroup SimtUtils SIMT Utilities - * \ingroup Simt - */ - -/** - * \defgroup HostUtil Host Utilities - */ diff --git a/cub/docs/.gitignore b/docs/.gitignore similarity index 70% rename from cub/docs/.gitignore rename to docs/.gitignore index 58a12a5a3e..4054350939 100644 --- a/cub/docs/.gitignore +++ b/docs/.gitignore @@ -1,2 +1 @@ -/html /citelist.doc diff --git a/cub/docs/Doxyfile b/docs/Doxyfile similarity index 96% rename from cub/docs/Doxyfile rename to docs/Doxyfile index f31b2fbcd1..2f98a87990 100644 --- a/cub/docs/Doxyfile +++ b/docs/Doxyfile @@ -664,7 +664,20 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../cub.cuh ../debug.cuh ../warp/warp_scan.cuh ../block/block_reduce.cuh ../block/block_scan.cuh ../block/block_radix_sort.cuh ../block/block_load.cuh ../block/block_store.cuh ../block/block_exchange.cuh ../block/block_discontinuity.cuh ../operators.cuh ../type_utils.cuh ../thread/thread_load.cuh ../thread/thread_store.cuh +INPUT = mainpage.dox +INPUT += ../cub/operators.cuh +INPUT += ../cub/type_utils.cuh +INPUT += ../cub/debug.cuh +INPUT += ../cub/warp/warp_scan.cuh +INPUT += ../cub/block/block_reduce.cuh +INPUT += ../cub/block/block_scan.cuh +INPUT += ../cub/block/block_radix_sort.cuh +INPUT += ../cub/block/block_load.cuh +INPUT += ../cub/block/block_store.cuh +INPUT += ../cub/block/block_exchange.cuh +INPUT += ../cub/block/block_discontinuity.cuh +INPUT += ../cub/thread/thread_load.cuh +INPUT += ../cub/thread/thread_store.cuh # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -927,7 +940,16 @@ HTML_EXTRA_STYLESHEET = extra_stylesheet.css # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. -HTML_EXTRA_FILES = images/download-icon.png images/groups-icon.png images/github-icon-747d8b799a48162434b2c0595ba1317e.png images/favicon.ico images/favicon.png images/tab_b_alt.png images/simt_abstraction.png images/kernel_abstraction.png images/devfun_abstraction.png +HTML_EXTRA_FILES = download_cub.html +HTML_EXTRA_FILES += images/download-icon.png +HTML_EXTRA_FILES += images/groups-icon.png +HTML_EXTRA_FILES += images/github-icon-747d8b799a48162434b2c0595ba1317e.png +HTML_EXTRA_FILES += images/favicon.ico +HTML_EXTRA_FILES += images/favicon.png +HTML_EXTRA_FILES += images/tab_b_alt.png +HTML_EXTRA_FILES += images/simt_abstraction.png +HTML_EXTRA_FILES += images/kernel_abstraction.png +HTML_EXTRA_FILES += images/devfun_abstraction.png # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images diff --git a/cub/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml similarity index 100% rename from cub/docs/DoxygenLayout.xml rename to docs/DoxygenLayout.xml diff --git a/docs/download_cub.html b/docs/download_cub.html new file mode 100644 index 0000000000..5fe0be4517 --- /dev/null +++ b/docs/download_cub.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + +
+If your download doesn't start in 3s: +

+ +Download CUB! +
+ + + \ No newline at end of file diff --git a/cub/docs/extra_stylesheet.css b/docs/extra_stylesheet.css similarity index 100% rename from cub/docs/extra_stylesheet.css rename to docs/extra_stylesheet.css diff --git a/cub/docs/footer.html b/docs/footer.html similarity index 100% rename from cub/docs/footer.html rename to docs/footer.html diff --git a/cub/docs/header.html b/docs/header.html similarity index 100% rename from cub/docs/header.html rename to docs/header.html diff --git a/docs/html/annotated.html b/docs/html/annotated.html new file mode 100644 index 0000000000..3e5e92c027 --- /dev/null +++ b/docs/html/annotated.html @@ -0,0 +1,171 @@ + + + + + + + +CUB: Class List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + +
\NcubCUB namespace
 oCArrayTraitsArray traits
 oCBaseTraitsBasic type traits
 oCBlockDiscontinuityBlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+
 oCBlockExchangeBlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+
 oCBlockLoadBlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+
 oCBlockRadixSortBlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+
 oCBlockReduceBlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+
 oCBlockScanBlockScan provides variants of parallel prefix scan (and prefix sum) across a CUDA threadblock.

+
+scan_logo.png +
+
 oCBlockStoreBlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+
 oCEnableIfSimple enable-if (similar to Boost)
 oCEqualityDefault equality functor
 oCEqualsType equality test
 oCIfType selection (IF ? ThenType : ElseType)
 oCIsVolatileVolatile modifier test
 oCLog2Statically determine log2(N), rounded up
 oCMaxDefault max functor
 oCNullTypeA simple "NULL" marker type
 oCNumericTraitsNumeric type traits
 oCRemoveQualifiersRemoves const and volatile qualifiers from type Tp
 oCSumDefault sum functor
 oCTraitsType traits
 \CWarpScanWarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+
+
+
+ + + + + diff --git a/docs/html/bc_s.png b/docs/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/docs/html/bdwn.png b/docs/html/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +CUB: block_discontinuity.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_discontinuity.cuh File Reference
+
+
+
#include <cuda_runtime.h>
+#include "../device_props.cuh"
+#include "../type_utils.cuh"
+#include "../operators.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Classes

class  cub::BlockDiscontinuity< T, BLOCK_THREADS >
 BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

cub::BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+ + + + + diff --git a/docs/html/block__exchange_8cuh.html b/docs/html/block__exchange_8cuh.html new file mode 100644 index 0000000000..192a7752d1 --- /dev/null +++ b/docs/html/block__exchange_8cuh.html @@ -0,0 +1,135 @@ + + + + + + + +CUB: block_exchange.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_exchange.cuh File Reference
+
+
+
#include "../ns_wrapper.cuh"
+#include "../device_props.cuh"
+#include "../ptx_intrinsics.cuh"
+#include "../type_utils.cuh"
+
+ + + + +

+Classes

class  cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >
 BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

cub::BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+ + + + + diff --git a/docs/html/block__load_8cuh.html b/docs/html/block__load_8cuh.html new file mode 100644 index 0000000000..8fbc5e018c --- /dev/null +++ b/docs/html/block__load_8cuh.html @@ -0,0 +1,210 @@ + + + + + + + +CUB: block_load.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_load.cuh File Reference
+
+
+
#include <iterator>
+#include "../ns_wrapper.cuh"
+#include "../macro_utils.cuh"
+#include "../thread/thread_load.cuh"
+#include "../type_utils.cuh"
+#include "../vector_type.cuh"
+#include "block_exchange.cuh"
+
+ + + + +

+Classes

class  cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
 BlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + +

+Enumerations

enum  cub::BlockLoadPolicy { cub::BLOCK_LOAD_DIRECT, +cub::BLOCK_LOAD_VECTORIZE, +cub::BLOCK_LOAD_TRANSPOSE + }
 Tuning policy for cub::BlockLoad. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

Direct threadblock loads (blocked arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly, guarded by range. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier, guarded by range, with assignment for out-of-bound elements. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly, guarded by range, with assignment for out-of-bound elements. More...
 
Direct threadblock loads (striped arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped directly tile using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly, guarded by range. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped directly tile using the specified cache modifier, guarded by range, with assignment for out-of-bound elements. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly, guarded by range, with assignment for out-of-bound elements. More...
 
Threadblock vectorized loads (blocked arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void cub::BlockLoadVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void cub::BlockLoadVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly. More...
 
+

Detailed Description

+

Operations for reading global tiles of data into the threadblock (in blocked arrangement across threads).

+
+ + + + + diff --git a/docs/html/block__radix__sort_8cuh.html b/docs/html/block__radix__sort_8cuh.html new file mode 100644 index 0000000000..322dfc139a --- /dev/null +++ b/docs/html/block__radix__sort_8cuh.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: block_radix_sort.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_radix_sort.cuh File Reference
+
+
+
#include "../ns_wrapper.cuh"
+#include "../device_props.cuh"
+#include "../type_utils.cuh"
+#include "block_exchange.cuh"
+#include "block_radix_rank.cuh"
+
+ + + + +

+Classes

class  cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >
 BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

cub::BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+ + + + + diff --git a/docs/html/block__reduce_8cuh.html b/docs/html/block__reduce_8cuh.html new file mode 100644 index 0000000000..262b923b11 --- /dev/null +++ b/docs/html/block__reduce_8cuh.html @@ -0,0 +1,138 @@ + + + + + + + +CUB: block_reduce.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_reduce.cuh File Reference
+
+
+
#include "../block/block_raking_grid.cuh"
+#include "../device_props.cuh"
+#include "../operators.cuh"
+#include "../thread/thread_reduce.cuh"
+#include "../thread/thread_load.cuh"
+#include "../thread/thread_store.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Classes

class  cub::BlockReduce< T, BLOCK_THREADS >
 BlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

cub::BlockReduce provides variants of parallel reduction across a CUDA threadblock

+
+ + + + + diff --git a/docs/html/block__scan_8cuh.html b/docs/html/block__scan_8cuh.html new file mode 100644 index 0000000000..591a6077bc --- /dev/null +++ b/docs/html/block__scan_8cuh.html @@ -0,0 +1,147 @@ + + + + + + + +CUB: block_scan.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_scan.cuh File Reference
+
+
+
#include "../device_props.cuh"
+#include "../type_utils.cuh"
+#include "../operators.cuh"
+#include "../warp/warp_scan.cuh"
+#include "../thread/thread_reduce.cuh"
+#include "../thread/thread_scan.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Classes

class  cub::BlockScan< T, BLOCK_THREADS, POLICY >
 BlockScan provides variants of parallel prefix scan (and prefix sum) across a CUDA threadblock.

+
+scan_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + +

+Enumerations

enum  cub::BlockScanPolicy { cub::BLOCK_SCAN_RAKING, +cub::BLOCK_SCAN_WARPSCANS + }
 Tuning policy for cub::BlockScan. More...
 
+

Detailed Description

+

cub::BlockScan provides variants of parallel prefix scan across a CUDA threadblock.

+
+ + + + + diff --git a/docs/html/block__store_8cuh.html b/docs/html/block__store_8cuh.html new file mode 100644 index 0000000000..ac9e2843a4 --- /dev/null +++ b/docs/html/block__store_8cuh.html @@ -0,0 +1,193 @@ + + + + + + + +CUB: block_store.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
block_store.cuh File Reference
+
+
+
#include <iterator>
+#include "../ns_wrapper.cuh"
+#include "../macro_utils.cuh"
+#include "../thread/thread_store.cuh"
+#include "../type_utils.cuh"
+#include "../vector_type.cuh"
+#include "block_exchange.cuh"
+
+ + + + +

+Classes

class  cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
 BlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + +

+Enumerations

enum  cub::BlockStorePolicy { cub::BLOCK_STORE_DIRECT, +cub::BLOCK_STORE_VECTORIZE, +cub::BLOCK_STORE_TRANSPOSE + }
 Tuning policy for cub::BlockStore. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

Direct threadblock stores (blocked arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void cub::BlockStoreDirect (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void cub::BlockStoreDirect (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly. More...
 
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockStoreDirect (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockStoreDirect (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly, guarded by range. More...
 
Direct threadblock stores (striped arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void cub::BlockStoreDirectStriped (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void cub::BlockStoreDirectStriped (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly. More...
 
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockStoreDirectStriped (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void cub::BlockStoreDirectStriped (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly, guarded by range. More...
 
Threadblock vectorized stores (blocked arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void cub::BlockStoreVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void cub::BlockStoreVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly. More...
 
+

Detailed Description

+

Operations for writing global tiles of data from the threadblock (in blocked arrangement across threads).

+
+ + + + + diff --git a/cub/docs/images/block_load_logo.png b/docs/html/block_load_logo.png similarity index 100% rename from cub/docs/images/block_load_logo.png rename to docs/html/block_load_logo.png diff --git a/cub/docs/images/block_reduce.png b/docs/html/block_reduce.png similarity index 100% rename from cub/docs/images/block_reduce.png rename to docs/html/block_reduce.png diff --git a/cub/docs/images/block_scan_raking.png b/docs/html/block_scan_raking.png similarity index 100% rename from cub/docs/images/block_scan_raking.png rename to docs/html/block_scan_raking.png diff --git a/cub/docs/images/block_scan_warpscans.png b/docs/html/block_scan_warpscans.png similarity index 100% rename from cub/docs/images/block_scan_warpscans.png rename to docs/html/block_scan_warpscans.png diff --git a/cub/docs/images/block_store_logo.png b/docs/html/block_store_logo.png similarity index 100% rename from cub/docs/images/block_store_logo.png rename to docs/html/block_store_logo.png diff --git a/cub/docs/images/blocked.png b/docs/html/blocked.png similarity index 100% rename from cub/docs/images/blocked.png rename to docs/html/blocked.png diff --git a/docs/html/citelist.html b/docs/html/citelist.html new file mode 100644 index 0000000000..7cb5cdf4e4 --- /dev/null +++ b/docs/html/citelist.html @@ -0,0 +1,110 @@ + + + + + + + +CUB: Bibliographic References + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Bibliographic References
+
+
+
+
[1]
+

Duane Merrill and Andrew Grimshaw. High performance and scalable radix sorting: A case study of implementing dynamic parallelism for GPU computing. Parallel Processing Letters, 21(02):245–272, 2011.

+

+
+
+
+ + + + + diff --git a/docs/html/classcub_1_1_block_discontinuity-members.html b/docs/html/classcub_1_1_block_discontinuity-members.html new file mode 100644 index 0000000000..63af424a23 --- /dev/null +++ b/docs/html/classcub_1_1_block_discontinuity-members.html @@ -0,0 +1,124 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockDiscontinuity< T, BLOCK_THREADS > Member List
+
+
+ +

This is the complete list of members for cub::BlockDiscontinuity< T, BLOCK_THREADS >, including all inherited members.

+ + + + + + +
Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)cub::BlockDiscontinuity< T, BLOCK_THREADS >inlinestatic
Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])cub::BlockDiscontinuity< T, BLOCK_THREADS >inlinestatic
Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)cub::BlockDiscontinuity< T, BLOCK_THREADS >inlinestatic
Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])cub::BlockDiscontinuity< T, BLOCK_THREADS >inlinestatic
SmemStorage typedefcub::BlockDiscontinuity< T, BLOCK_THREADS >
+ + + + + diff --git a/docs/html/classcub_1_1_block_discontinuity.html b/docs/html/classcub_1_1_block_discontinuity.html new file mode 100644 index 0000000000..9526319660 --- /dev/null +++ b/docs/html/classcub_1_1_block_discontinuity.html @@ -0,0 +1,548 @@ + + + + + + + +CUB: cub::BlockDiscontinuity< T, BLOCK_THREADS > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockDiscontinuity< T, BLOCK_THREADS > Class Template Reference
+
+
+

Detailed description

+

template<typename T, int BLOCK_THREADS>
+class cub::BlockDiscontinuity< T, BLOCK_THREADS >

+ +

BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+.
+
Overview
The operations exposed by BlockDiscontinuity allow threadblocks to set "head flags" for data elements that are different from their predecessor (as specified by a binary boolean operator). Head flags are often useful for orchestrating segmented scans and reductions.
+
For convenience, BlockDiscontinuity exposes a spectrum of entrypoints that differ by:
    +
  • How the first item is handled (always-flagged vs. compared to a specific block-wide predecessor)
  • +
  • Output (discontinuity flags only vs. discontinuity flags and a copy of the last tile item for thread0)
  • +
+
+
Template Parameters
+ + + +
TThe data type to be exchanged.
BLOCK_THREADSThe threadblock size in threads.
+
+
+
Usage Considerations
    +
  • Assumes a blocked arrangement of elements across threads
  • +
  • Any threadblock-wide scalar inputs and outputs (e.g., tile_predecessor and last_tile_item) are only considered valid in thread0
  • +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied BlockDiscontinuity::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
    +
  • Zero bank conflicts for most types.
  • +
+
+
Examples
Example 1. Given a tile of 512 non-zero matrix coordinates (ordered by row) in a blocked arrangement across a 128-thread threadblock, flag the first coordinate element of each row.
#include <cub.cuh>
+
+
struct NonZero
+
{
+
int row;
+
int col;
+
float val;
+
};
+
+
struct NewRowOp
+
{
+
__device__ __forceinline__ bool operator()(
+
const NonZero& a,
+
const NonZero& b)
+
{
+
return (a.row != b.row);
+
}
+
};
+
+
__global__ void SomeKernel(...)
+
{
+
// Parameterize BlockDiscontinuity for the parallel execution context
+
typedef cub::BlockDiscontinuity<NonZero, 128> BlockDiscontinuity;
+
+
// Declare shared memory for BlockDiscontinuity
+
__shared__ typename BlockDiscontinuity::SmemStorage smem_storage;
+
+
// A segment of consecutive non-zeroes per thread
+
NonZero coordinates[4];
+
+
// Obtain items in blocked order
+
...
+
+
// Obtain the last item of the previous tile
+
NonZero block_predecessor;
+
if (threadIdx.x == 0)
+
{
+
block_predecessor = ...
+
}
+
+
// Set head flags
+
int head_flags[4];
+
BlockDiscontinuity::Flag(smem_storage, coordinates, block_predecessor, NewRowOp(), head_flags);
+
+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by BlockDiscontinuity require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + + + + + + + + + + +

+Static Public Methods

template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
static __device__
+__forceinline__ void 
Flag (SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)
 Sets discontinuity flags for a tile of threadblock items, for which the first item has no reference (and is always flagged). The last tile item of the last thread is also returned to thread0. More...
 
template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
static __device__
+__forceinline__ void 
Flag (SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])
 Sets discontinuity flags for a tile of threadblock items, for which the first item has no reference (and is always flagged). More...
 
template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
static __device__
+__forceinline__ void 
Flag (SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)
 Sets discontinuity flags for a tile of threadblock items. The last tile item of the last thread is also returned to thread0. More...
 
template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
static __device__
+__forceinline__ void 
Flag (SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])
 Sets discontinuity flags for a tile of threadblock items. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockDiscontinuity< T, BLOCK_THREADS >::Flag (SmemStoragesmem_storage,
T(&) input[ITEMS_PER_THREAD],
FlagOp flag_op,
FlagT(&) flags[ITEMS_PER_THREAD],
T & last_tile_item 
)
+
+inlinestatic
+
+ +

Sets discontinuity flags for a tile of threadblock items, for which the first item has no reference (and is always flagged). The last tile item of the last thread is also returned to thread0.

+

Assuming a blocked arrangement of elements across threads, flagsi is set non-zero for item inputi when scan_op(previous-item, inputi) is true (where previous-item is either inputi-1, or inputITEMS_PER_THREAD-1 in the previous thread). Furthermore, flagsi is always non-zero for input0 in thread0.

+

The last_tile_item is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
FlagT[inferred] The flag type (must be an integer type)
FlagOp[inferred] Binary boolean functor type, having input parameters (const T &a, const T &b) and returning true if a discontinuity exists between a and b, otherwise false.
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputInput items
[in]flag_opBinary boolean flag predicate
[out]flagsDiscontinuity flags
[out]last_tile_item[thread0 only] The last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1)
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockDiscontinuity< T, BLOCK_THREADS >::Flag (SmemStoragesmem_storage,
T(&) input[ITEMS_PER_THREAD],
FlagOp flag_op,
FlagT(&) flags[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Sets discontinuity flags for a tile of threadblock items, for which the first item has no reference (and is always flagged).

+

Assuming a blocked arrangement of elements across threads, flagsi is set non-zero for item inputi when scan_op(previous-item, inputi) is true (where previous-item is either inputi-1, or inputITEMS_PER_THREAD-1 in the previous thread). Furthermore, flagsi is always non-zero for input0 in thread0.

+

The last_tile_item is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
FlagT[inferred] The flag type (must be an integer type)
FlagOp[inferred] Binary boolean functor type, having input parameters (const T &a, const T &b) and returning true if a discontinuity exists between a and b, otherwise false.
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputInput items
[in]flag_opBinary boolean flag predicate
[out]flagsDiscontinuity flags
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockDiscontinuity< T, BLOCK_THREADS >::Flag (SmemStoragesmem_storage,
T(&) input[ITEMS_PER_THREAD],
tile_predecessor,
FlagOp flag_op,
FlagT(&) flags[ITEMS_PER_THREAD],
T & last_tile_item 
)
+
+inlinestatic
+
+ +

Sets discontinuity flags for a tile of threadblock items. The last tile item of the last thread is also returned to thread0.

+

Assuming a blocked arrangement of elements across threads, flagsi is set non-zero for item inputi when scan_op(previous-item, inputi) is true (where previous-item is either inputi-1, or inputITEMS_PER_THREAD-1 in the previous thread). For thread0, item input0 is compared against /p tile_predecessor.

+

The tile_predecessor and last_tile_item are undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
FlagT[inferred] The flag type (must be an integer type)
FlagOp[inferred] Binary boolean functor type, having input parameters (const T &a, const T &b) and returning true if a discontinuity exists between a and b, otherwise false.
+
+
+
Parameters
+ + + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputInput items
[in]tile_predecessor[thread0 only] Item with which to compare the first tile item (input0from thread0).
[in]flag_opBinary boolean flag predicate
[out]flagsDiscontinuity flags
[out]last_tile_item[thread0 only] The last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1)
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD, typename FlagT , typename FlagOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockDiscontinuity< T, BLOCK_THREADS >::Flag (SmemStoragesmem_storage,
T(&) input[ITEMS_PER_THREAD],
tile_predecessor,
FlagOp flag_op,
FlagT(&) flags[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Sets discontinuity flags for a tile of threadblock items.

+

Assuming a blocked arrangement of elements across threads, flagsi is set non-zero for item inputi when scan_op(previous-item, inputi) is true (where previous-item is either inputi-1, or inputITEMS_PER_THREAD-1 in the previous thread). For thread0, item input0 is compared against /p tile_predecessor.

+

The tile_predecessor and last_tile_item are undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
FlagT[inferred] The flag type (must be an integer type)
FlagOp[inferred] Binary boolean functor type, having input parameters (const T &a, const T &b) and returning true if a discontinuity exists between a and b, otherwise false.
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputInput items
[in]tile_predecessor[thread0 only] Item with which to compare the first tile item (input0from thread0).
[in]flag_opBinary boolean flag predicate
[out]flagsDiscontinuity flags
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_block_exchange-members.html b/docs/html/classcub_1_1_block_exchange-members.html new file mode 100644 index 0000000000..57bee0babe --- /dev/null +++ b/docs/html/classcub_1_1_block_exchange-members.html @@ -0,0 +1,124 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD > Member List
+
+
+ +

This is the complete list of members for cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >, including all inherited members.

+ + + + + + +
BlockedToStriped(SmemStorage &smem_storage, T items[ITEMS_PER_THREAD])cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >inlinestatic
ScatterToBlocked(SmemStorage &smem_storage, T items[ITEMS_PER_THREAD], unsigned int ranks[ITEMS_PER_THREAD])cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >inlinestatic
ScatterToStriped(SmemStorage &smem_storage, T items[ITEMS_PER_THREAD], unsigned int ranks[ITEMS_PER_THREAD])cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >inlinestatic
SmemStorage typedefcub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >
StripedToBlocked(SmemStorage &smem_storage, T items[ITEMS_PER_THREAD])cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >inlinestatic
+ + + + + diff --git a/docs/html/classcub_1_1_block_exchange.html b/docs/html/classcub_1_1_block_exchange.html new file mode 100644 index 0000000000..422b16d501 --- /dev/null +++ b/docs/html/classcub_1_1_block_exchange.html @@ -0,0 +1,386 @@ + + + + + + + +CUB: cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD > Class Template Reference
+
+
+

Detailed description

+

template<typename T, int BLOCK_THREADS, int ITEMS_PER_THREAD>
+class cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >

+ +

BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+.
+
Overview
BlockExchange allows threadblocks to reorganize data items between threads. More specifically, BlockExchange supports the following types of data exchanges: +
+
Template Parameters
+ + + + +
TThe data type to be exchanged.
BLOCK_THREADSThe threadblock size in threads.
ITEMS_PER_THREADThe number of items partitioned onto each thread.
+
+
+
Algorithm
Threads scatter items by item-order into shared memory, allowing one item of padding for every memory bank's worth of items. After a barrier, items are gathered in the desired arrangement.
+raking.png +
+
A threadblock of 16 threads reading a blocked arrangement of 64 items in a parallel "raking" fashion.
+
Usage Considerations
    +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied BlockExchange::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
    +
  • Proper device-specific padding ensures zero bank conflicts for most types.
  • +
+
+
+ + + + +

+Public Types

+typedef SmemStorage SmemStorage
 The operations exposed by BlockExchange require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + + + + + + + + +

+Static Public Methods

Transpose exchanges
static __device__
+__forceinline__ void 
BlockedToStriped (SmemStorage &smem_storage, T items[ITEMS_PER_THREAD])
 Transposes data items from blocked arrangement to striped arrangement. More...
 
static __device__
+__forceinline__ void 
StripedToBlocked (SmemStorage &smem_storage, T items[ITEMS_PER_THREAD])
 Transposes data items from striped arrangement to blocked arrangement. More...
 
Scatter exchanges
static __device__
+__forceinline__ void 
ScatterToBlocked (SmemStorage &smem_storage, T items[ITEMS_PER_THREAD], unsigned int ranks[ITEMS_PER_THREAD])
 Exchanges data items annotated by rank into blocked arrangement. More...
 
static __device__
+__forceinline__ void 
ScatterToStriped (SmemStorage &smem_storage, T items[ITEMS_PER_THREAD], unsigned int ranks[ITEMS_PER_THREAD])
 Exchanges data items annotated by rank into striped arrangement. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename T , int BLOCK_THREADS, int ITEMS_PER_THREAD>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >::BlockedToStriped (SmemStoragesmem_storage,
items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Transposes data items from blocked arrangement to striped arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]itemsItems to exchange, converting between blocked and striped arrangements.
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS, int ITEMS_PER_THREAD>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >::StripedToBlocked (SmemStoragesmem_storage,
items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Transposes data items from striped arrangement to blocked arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]itemsItems to exchange, converting between striped and blocked arrangements.
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS, int ITEMS_PER_THREAD>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >::ScatterToBlocked (SmemStoragesmem_storage,
items[ITEMS_PER_THREAD],
unsigned int ranks[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Exchanges data items annotated by rank into blocked arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]itemsItems to exchange
[in]ranksCorresponding scatter ranks
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS, int ITEMS_PER_THREAD>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >::ScatterToStriped (SmemStoragesmem_storage,
items[ITEMS_PER_THREAD],
unsigned int ranks[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Exchanges data items annotated by rank into striped arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]itemsItems to exchange
[in]ranksCorresponding scatter ranks
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_block_load-members.html b/docs/html/classcub_1_1_block_load-members.html new file mode 100644 index 0000000000..17dc1f739c --- /dev/null +++ b/docs/html/classcub_1_1_block_load-members.html @@ -0,0 +1,122 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Member List
+
+
+ +

This is the complete list of members for cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >, including all inherited members.

+ + + + +
Load(SmemStorage &smem_storage, InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >inlinestatic
Load(SmemStorage &smem_storage, InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >inlinestatic
SmemStorage typedefcub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
+ + + + + diff --git a/docs/html/classcub_1_1_block_load.html b/docs/html/classcub_1_1_block_load.html new file mode 100644 index 0000000000..0251f4619e --- /dev/null +++ b/docs/html/classcub_1_1_block_load.html @@ -0,0 +1,338 @@ + + + + + + + +CUB: cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Class Template Reference
+
+
+

Detailed description

+

template<typename InputIterator, int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockLoadPolicy POLICY = BLOCK_LOAD_DIRECT, PtxLoadModifier MODIFIER = PTX_LOAD_NONE>
+class cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >

+ +

BlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+.
+

BlockLoad provides a single tile-loading abstraction whose performance behavior can be statically tuned. In particular, BlockLoad implements alternative cub::BlockLoadPolicy strategies catering to different granularity sizes (i.e., number of items per thread).

+
Template Parameters
+ + + + + + +
InputIteratorThe input iterator type (may be a simple pointer type).
BLOCK_THREADSThe threadblock size in threads.
ITEMS_PER_THREADThe number of consecutive items partitioned onto each thread.
POLICY[optional] cub::BlockLoadPolicy tuning policy. Default = cub::BLOCK_LOAD_DIRECT.
MODIFIER[optional] cub::PtxLoadModifier cache modifier. Default = cub::PTX_LOAD_NONE.
+
+
+
Algorithm
BlockLoad can be (optionally) configured to use one of three alternative methods:
    +
  1. cub::BLOCK_LOAD_DIRECT. A blocked arrangement of data is read directly from memory. More...
  2. +
  3. cub::BLOCK_LOAD_VECTORIZE. A blocked arrangement of data is read directly from memory using CUDA's built-in vectorized loads as a coalescing optimization. More...
  4. +
  5. cub::BLOCK_LOAD_TRANSPOSE. A striped arrangement of data is read directly from memory and is then locally transposed into a blocked arrangement. More...
  6. +
+
+
Usage Considerations
    +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied BlockLoad::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
+
+
Examples
Example 1. Have a 128-thread threadblock directly load a blocked arrangement of four consecutive integers per thread.
#include <cub.cuh>
+
+
__global__ void SomeKernel(int *d_in, ...)
+
{
+
// Parameterize BlockLoad for the parallel execution context
+
typedef cub::BlockLoad<int*, 128, 4> BlockLoad;
+
+
// Declare shared memory for BlockLoad
+
__shared__ typename BlockLoad::SmemStorage smem_storage;
+
+
// A segment of consecutive items per thread
+
int data[4];
+
+
// Load a tile of data at this block's offset
+
BlockLoad::Load(smem_storage, d_in + blockIdx.x * 128 * 4, data);
+
+
...
+
+
Example 2. Have a threadblock load a blocked arrangement of ITEMS_PER_THREAD consecutive integers per thread using vectorized loads and global-only caching:
#include <cub.cuh>
+
+
template <
+
int BLOCK_THREADS,
+
int ITEMS_PER_THREAD>
+
__global__ void SomeKernel(int *d_in, ...)
+
{
+
// Parameterize BlockLoad for the parallel execution context
+ +
+
// Declare shared memory for BlockLoad
+
__shared__ typename BlockLoad::SmemStorage smem_storage;
+
+
// A segment of consecutive items per thread
+
int data[ITEMS_PER_THREAD];
+
+
// Load a tile of data at this block's offset
+
BlockLoad::Load(smem_storage, d_in + blockIdx.x * BLOCK_THREADS * ITEMS_PER_THREAD, data);
+
+
...
+

+
+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by BlockLoad require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + +

+Static Public Methods

static __device__
+__forceinline__ void 
Load (SmemStorage &smem_storage, InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock. More...
 
template<typename SizeT >
static __device__
+__forceinline__ void 
Load (SmemStorage &smem_storage, InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock, guarded by range. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename InputIterator , int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockLoadPolicy POLICY = BLOCK_LOAD_DIRECT, PtxLoadModifier MODIFIER = PTX_LOAD_NONE>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >::Load (SmemStoragesmem_storage,
InputIterator block_itr,
T(&) items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Load a tile of items across a threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]block_itrThe threadblock's base input iterator for loading from
[out]itemsData to load
+
+
+ +
+
+ +
+
+
+template<typename InputIterator , int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockLoadPolicy POLICY = BLOCK_LOAD_DIRECT, PtxLoadModifier MODIFIER = PTX_LOAD_NONE>
+
+template<typename SizeT >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >::Load (SmemStoragesmem_storage,
InputIterator block_itr,
const SizeT & guarded_items,
T(&) items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Load a tile of items across a threadblock, guarded by range.

+
Template Parameters
+ + +
SizeT[inferred] Integer type for offsets
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]block_itrThe threadblock's base input iterator for loading from
[in]guarded_itemsNumber of valid items in the tile
[out]itemsData to load
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_block_radix_sort-members.html b/docs/html/classcub_1_1_block_radix_sort-members.html new file mode 100644 index 0000000000..90c56f20a2 --- /dev/null +++ b/docs/html/classcub_1_1_block_radix_sort-members.html @@ -0,0 +1,126 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG > Member List
+
+
+ +

This is the complete list of members for cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >, including all inherited members.

+ + + + + + + + +
SmemStorage typedefcub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >
SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >inlinestatic
+ + + + + diff --git a/docs/html/classcub_1_1_block_radix_sort.html b/docs/html/classcub_1_1_block_radix_sort.html new file mode 100644 index 0000000000..818ce8ce91 --- /dev/null +++ b/docs/html/classcub_1_1_block_radix_sort.html @@ -0,0 +1,629 @@ + + + + + + + +CUB: cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG > Class Template Reference
+
+
+

Detailed description

+

template<typename KeyType, int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+class cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >

+ +

BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+.
+
Overview
The radix sorting method relies upon a positional representation for keys, i.e., each key is comprised of an ordered sequence of symbols (e.g., digits, characters, etc.) specified from least-significant to most-significant. For a given input sequence of keys and a set of rules specifying a total ordering of the symbolic alphabet, the radix sorting method produces a lexicographic ordering of those keys.
+
BlockRadixSort can sort all of the built-in C++ numeric primitive types, e.g.: unsigned char, int, double, etc. Within each key, the implementation treats fixed-length bit-sequences of RADIX_BITS as radix digit places. Although the direct radix sorting method can only be applied to unsigned integral types, BlockRadixSort is able to sort signed and floating-point types via simple bit-wise transformations that ensure lexicographic key ordering.
+
For convenience, BlockRadixSort exposes a spectrum of entrypoints that differ by:
    +
  • Value association (keys-only vs. key-value-pairs)
  • +
  • Input/output data arrangements (combinations of blocked and striped arrangements)
  • +
+
+
Template Parameters
+ + + + + + + +
KeyTypeKey type
BLOCK_THREADSThe threadblock size in threads
ITEMS_PER_THREADThe number of items per thread
ValueType[optional] Value type (default: cub::NullType)
RADIX_BITS[optional] The number of radix bits per digit place (default: 5 bits)
SMEM_CONFIG[optional] Shared memory bank mode (default: cudaSharedMemBankSizeFourByte)
+
+
+
Usage Considerations
    +
  • After any sorting operation, a subsequent __syncthreads() barrier is required if the supplied BlockRadixSort::SmemStorage is to be reused or repurposed by the threadblock.
  • +
  • BlockRadixSort can only accommodate one associated tile of values. To "truck along" more than one tile of values, simply perform a key-value sort of the keys paired with a temporary value array that enumerates the key indices. The reordered indices can then be used as a gather-vector for exchanging other associated tile data through shared memory.
  • +
+
+
Performance Considerations
    +
  • The operations are most efficient (lowest instruction overhead) when:
      +
    • BLOCK_THREADS is a multiple of the architecture's warp size
    • +
    • KeyType is an unsigned integral type
    • +
    • Keys are partitioned across the threadblock in a blocked arrangement
    • +
    +
  • +
+
+
Algorithm
BlockRadixSort is based on the method presented by Merrill et al.[1]. The implementation has O(n) work complexity and iterates over digit places using rounds constructed of +
+
Examples
Example 1. Perform a radix sort over a tile of 512 integer keys that are partitioned in a blocked arrangement across a 128-thread threadblock (where each thread holds 4 keys).
#include <cub.cuh>
+
+
__global__ void SomeKernel(...)
+
{
+
// Parameterize BlockRadixSort for the parallel execution context
+ +
+
// Declare shared memory for BlockRadixSort
+
__shared__ typename BlockRadixSort::SmemStorage smem_storage;
+
+
// A segment of consecutive input items per thread
+
int keys[4];
+
+
// Obtain keys in blocked order
+
...
+
+
// Sort keys in ascending order
+
BlockRadixSort::SortBlocked(smem_storage, keys);
+
+
Example 2. Perform a key-value radix sort over the lower 20-bits of a tile of 32-bit integer keys paired with floating-point values. The data are partitioned in a striped arrangement across the threadblock.
#include <cub.cuh>
+
+
template <int BLOCK_THREADS, int ITEMS_PER_THREAD>
+
__global__ void SomeKernel(...)
+
{
+
// Parameterize BlockRadixSort for the parallel execution context
+ +
+
// Declare shared memory for BlockRadixSort
+
__shared__ typename BlockRadixSort::SmemStorage smem_storage;
+
+
// Input keys and values per thread (striped across the threadblock)
+
int keys[ITEMS_PER_THREAD];
+
float values[ITEMS_PER_THREAD];
+
+
// Obtain keys and values in striped order
+
...
+
+
// Sort pairs in ascending order (using only the lower 20 distinguishing key bits)
+
BlockRadixSort::SortStriped(smem_storage, keys, values, 0, 20);
+
}
+
+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by BlockRadixSort require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + + + + + + + + + + + + + + +

+Static Public Methods

Keys-only sorting
static __device__
+__forceinline__ void 
SortBlocked (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a threadblock-wide radix sort over a blocked arrangement of keys. More...
 
static __device__
+__forceinline__ void 
SortBlockedToStriped (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a radix sort across a blocked arrangement of keys, leaving them in a striped arrangement. More...
 
static __device__
+__forceinline__ void 
SortStriped (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a radix sort across a striped arrangement of keys. More...
 
Key-value pair sorting
static __device__
+__forceinline__ void 
SortBlocked (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a radix sort across a blocked arrangement of keys and values. More...
 
static __device__
+__forceinline__ void 
SortBlockedToStriped (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a radix sort across a blocked arrangement of keys and values, leaving them in a striped arrangement. More...
 
static __device__
+__forceinline__ void 
SortStriped (SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)
 Performs a radix sort across a striped arrangement of keys and values. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortBlocked (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a threadblock-wide radix sort over a blocked arrangement of keys.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortBlockedToStriped (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a radix sort across a blocked arrangement of keys, leaving them in a striped arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortStriped (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a radix sort across a striped arrangement of keys.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortBlocked (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
ValueType(&) values[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a radix sort across a blocked arrangement of keys and values.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in,out]valuesValues to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortBlockedToStriped (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
ValueType(&) values[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a radix sort across a blocked arrangement of keys and values, leaving them in a striped arrangement.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in,out]valuesValues to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+ +
+
+
+template<typename KeyType , int BLOCK_THREADS, int ITEMS_PER_THREAD, typename ValueType = NullType, int RADIX_BITS = 5, cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >::SortStriped (SmemStoragesmem_storage,
KeyType(&) keys[ITEMS_PER_THREAD],
ValueType(&) values[ITEMS_PER_THREAD],
unsigned int begin_bit = 0,
const unsigned int & end_bit = sizeof(KeyType) * 8 
)
+
+inlinestatic
+
+ +

Performs a radix sort across a striped arrangement of keys and values.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in,out]keysKeys to sort
[in,out]valuesValues to sort
[in]begin_bit[optional] The beginning (least-significant) bit index needed for key comparison
[in]end_bit[optional] The past-the-end (most-significant) bit index needed for key comparison
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_block_reduce-members.html b/docs/html/classcub_1_1_block_reduce-members.html new file mode 100644 index 0000000000..a70842a582 --- /dev/null +++ b/docs/html/classcub_1_1_block_reduce-members.html @@ -0,0 +1,126 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockReduce< T, BLOCK_THREADS > Member List
+
+
+ +

This is the complete list of members for cub::BlockReduce< T, BLOCK_THREADS >, including all inherited members.

+ + + + + + + + +
Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op)cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
Reduce(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD], ReductionOp reduction_op)cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op, const unsigned int &valid_threads)cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
SmemStorage typedefcub::BlockReduce< T, BLOCK_THREADS >
Sum(SmemStorage &smem_storage, T input)cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
Sum(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD])cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
Sum(SmemStorage &smem_storage, T input, const unsigned int &valid_threads)cub::BlockReduce< T, BLOCK_THREADS >inlinestatic
+ + + + + diff --git a/docs/html/classcub_1_1_block_reduce.html b/docs/html/classcub_1_1_block_reduce.html new file mode 100644 index 0000000000..9120d57919 --- /dev/null +++ b/docs/html/classcub_1_1_block_reduce.html @@ -0,0 +1,601 @@ + + + + + + + +CUB: cub::BlockReduce< T, BLOCK_THREADS > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockReduce< T, BLOCK_THREADS > Class Template Reference
+
+
+

Detailed description

+

template<typename T, int BLOCK_THREADS>
+class cub::BlockReduce< T, BLOCK_THREADS >

+ +

BlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+.
+
Overview
A reduction (or fold) uses a binary combining operator to compute a single aggregate from a list of input elements.
+
For convenience, BlockReduce exposes a spectrum of entrypoints that differ by:
    +
  • Granularity (single vs. multiple items per thread)
  • +
  • Input (full tile vs. partial-tile having some undefined elements)
  • +
+
+
Template Parameters
+ + + +
TThe reduction input/output element type
BLOCK_THREADSThe threadblock size in threads
+
+
+
Algorithm
BlockReduce entrypoints have O(n) work complexity and are implemented in three phases:
    +
  1. Sequential reduction in registers (if threads contribute more than one input each). Each thread then places the partial reduction of its item(s) into shared memory.
  2. +
  3. A single-warp performs a raking upsweep across partial reductions shared each thread in the threadblock.
  4. +
  5. A warp-synchronous Kogge-Stone style reduction within the raking warp to produce the total aggregate.
    +block_reduce.png +
    +
    Data flow for a hypothetical 16-thread threadblock and 4-thread raking warp.
  6. +
+
+
Usage Considerations
    +
  • Supports non-commutative reduction operators
  • +
  • Supports partially-full threadblocks (i.e., the most-significant thread ranks having undefined values).
  • +
  • Assumes a blocked arrangement of elements across threads
  • +
  • The threadblock-wide scalar reduction output is only considered valid in thread0
  • +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied BlockReduce::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
    +
  • Very efficient (only one synchronization barrier).
  • +
  • Zero bank conflicts for most types.
  • +
  • Computation is slightly more efficient (i.e., having lower instruction overhead) for:
      +
    • T is a built-in C++ primitive or CUDA vector type (e.g., short, int2, double, float2, etc.)
    • +
    • BLOCK_THREADS is a multiple of the architecture's warp size
    • +
    • Every thread has a valid input (i.e., full vs. partial-tiles)
    • +
    +
  • +
+
+
Examples
+
Example 1. Perform a simple reduction of 512 integer keys that are partitioned in a blocked arrangement across a 128-thread threadblock (where each thread holds 4 keys).
#include <cub.cuh>
+
+
__global__ void SomeKernel(...)
+
{
+
// Parameterize BlockReduce for the parallel execution context
+
typedef cub::BlockReduce<int, 128> BlockReduce;
+
+
// Declare shared memory for BlockReduce
+
__shared__ typename BlockReduce::SmemStorage smem_storage;
+
+
// A segment of consecutive input items per thread
+
int data[4];
+
+
// Obtain items in blocked order
+
...
+
+
// Compute the threadblock-wide sum for thread0
+
int aggregate = BlockReduce::Sum(smem_storage, data);
+
+
...
+
+
Example 2: Perform a guarded reduction of only num_elements keys that are partitioned in a partially-full blocked arrangement across BLOCK_THREADS threads.
#include <cub.cuh>
+
+
template <int BLOCK_THREADS>
+
__global__ void SomeKernel(..., int num_elements)
+
{
+
// Parameterize BlockReduce for use with BLOCK_THREADS threads on type int
+ +
+
// Declare shared memory for BlockReduce
+
__shared__ typename BlockReduce::SmemStorage smem_storage;
+
+
// Guarded load
+
int data;
+
if (threadIdx.x < num_elements) data = ...;
+
+
// Compute the threadblock-wide sum of valid elements in thread0
+
int aggregate = BlockReduce::Sum(smem_storage, data, num_elements);
+
+
...
+
+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by BlockReduce require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Methods

Generic reductions
template<typename ReductionOp >
static __device__ __forceinline__ T Reduce (SmemStorage &smem_storage, T input, ReductionOp reduction_op)
 Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes one input element. More...
 
template<int ITEMS_PER_THREAD, typename ReductionOp >
static __device__ __forceinline__ T Reduce (SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD], ReductionOp reduction_op)
 Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes an array of consecutive input elements. More...
 
template<typename ReductionOp >
static __device__ __forceinline__ T Reduce (SmemStorage &smem_storage, T input, ReductionOp reduction_op, const unsigned int &valid_threads)
 Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. The first valid_threads threads each contribute one input element. More...
 
Summation reductions
static __device__ __forceinline__ T Sum (SmemStorage &smem_storage, T input)
 Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes one input element. More...
 
template<int ITEMS_PER_THREAD>
static __device__ __forceinline__ T Sum (SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD])
 Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes an array of consecutive input elements. More...
 
static __device__ __forceinline__ T Sum (SmemStorage &smem_storage, T input, const unsigned int &valid_threads)
 Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. The first valid_threads threads each contribute one input element. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<typename ReductionOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Reduce (SmemStoragesmem_storage,
input,
ReductionOp reduction_op 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes one input element.

+

The return value is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ReductionOp[inferred] Binary reduction functor type (a model of Binary Function).
+
+
+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input
[in]reduction_opBinary associative reduction functor
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD, typename ReductionOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Reduce (SmemStoragesmem_storage,
T(&) inputs[ITEMS_PER_THREAD],
ReductionOp reduction_op 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes an array of consecutive input elements.

+

The return value is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
ReductionOp[inferred] Binary reduction functor type (a model of Binary Function).
+
+
+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputsCalling thread's input segment
[in]reduction_opBinary associative reduction functor
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<typename ReductionOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Reduce (SmemStoragesmem_storage,
input,
ReductionOp reduction_op,
const unsigned int & valid_threads 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using the specified binary reduction functor. The first valid_threads threads each contribute one input element.

+

The return value is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ReductionOp[inferred] Binary reduction functor type (a model of Binary Function).
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input
[in]reduction_opBinary associative reduction functor
[in]valid_threadsNumber of threads containing valid elements (may be less than BLOCK_THREADS)
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Sum (SmemStoragesmem_storage,
input 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes one input element.

+

The return value is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+
+template<int ITEMS_PER_THREAD>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Sum (SmemStoragesmem_storage,
T(&) inputs[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes an array of consecutive input elements.

+

The return value is undefined in threads other than thread0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ITEMS_PER_THREAD[inferred] The number of consecutive items partitioned onto each thread.
+
+
+
Parameters
+ + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputsCalling thread's input segment
+
+
+ +
+
+ +
+
+
+template<typename T , int BLOCK_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ T cub::BlockReduce< T, BLOCK_THREADS >::Sum (SmemStoragesmem_storage,
input,
const unsigned int & valid_threads 
)
+
+inlinestatic
+
+ +

Computes a threadblock-wide reduction for thread0 using addition (+) as the reduction operator. The first valid_threads threads each contribute one input element.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+

The return value is undefined in threads other than thread0.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input
[in]valid_threadsNumber of threads containing valid elements (may be less than BLOCK_THREADS)
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_block_scan-members.html b/docs/html/classcub_1_1_block_scan-members.html new file mode 100644 index 0000000000..7d5fce93ae --- /dev/null +++ b/docs/html/classcub_1_1_block_scan-members.html @@ -0,0 +1,150 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockScan< T, BLOCK_THREADS, POLICY > Member List
+
+
+ +

This is the complete list of members for cub::BlockScan< T, BLOCK_THREADS, POLICY >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output)cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])cub::BlockScan< T, BLOCK_THREADS, POLICY >inlinestatic
SmemStorage typedefcub::BlockScan< T, BLOCK_THREADS, POLICY >
+ + + + + diff --git a/docs/html/classcub_1_1_block_scan.html.REMOVED.git-id b/docs/html/classcub_1_1_block_scan.html.REMOVED.git-id new file mode 100644 index 0000000000..71a6a74ff8 --- /dev/null +++ b/docs/html/classcub_1_1_block_scan.html.REMOVED.git-id @@ -0,0 +1 @@ +9610aa94f92ca87a6e60a940472ee60606ac256b \ No newline at end of file diff --git a/docs/html/classcub_1_1_block_store-members.html b/docs/html/classcub_1_1_block_store-members.html new file mode 100644 index 0000000000..f50b2f7688 --- /dev/null +++ b/docs/html/classcub_1_1_block_store-members.html @@ -0,0 +1,122 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Member List
+
+
+ +

This is the complete list of members for cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >, including all inherited members.

+ + + + +
SmemStorage typedefcub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
Store(SmemStorage &smem_storage, OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >inlinestatic
Store(SmemStorage &smem_storage, OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >inlinestatic
+ + + + + diff --git a/docs/html/classcub_1_1_block_store.html b/docs/html/classcub_1_1_block_store.html new file mode 100644 index 0000000000..ae1aac66b3 --- /dev/null +++ b/docs/html/classcub_1_1_block_store.html @@ -0,0 +1,342 @@ + + + + + + + +CUB: cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER > Class Template Reference
+
+
+

Detailed description

+

template<typename OutputIterator, int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockStorePolicy POLICY = BLOCK_STORE_DIRECT, PtxStoreModifier MODIFIER = PTX_STORE_NONE>
+class cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >

+ +

BlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+.
+

BlockStore provides a single tile-storing abstraction whose performance behavior can be statically tuned. In particular, BlockStore implements several alternative cub::BlockStorePolicy strategies catering to different granularity sizes (i.e., number of items per thread).

+
Template Parameters
+ + + + + + +
OutputIteratorThe input iterator type (may be a simple pointer type).
BLOCK_THREADSThe threadblock size in threads.
ITEMS_PER_THREADThe number of consecutive items partitioned onto each thread.
POLICY[optional] cub::BlockStorePolicy tuning policy enumeration. Default = cub::BLOCK_STORE_DIRECT.
MODIFIER[optional] cub::PtxStoreModifier cache modifier. Default = cub::PTX_STORE_NONE.
+
+
+
Algorithm
BlockStore can be (optionally) configured to use one of three alternative methods:
    +
  1. cub::BLOCK_STORE_DIRECT. A blocked arrangement of data is written directly to memory. More...
  2. +
  3. cub::BLOCK_STORE_VECTORIZE. A blocked arrangement of data is written directly to memory using CUDA's built-in vectorized stores as a coalescing optimization. More...
  4. +
  5. cub::BLOCK_STORE_TRANSPOSE. A blocked arrangement is locally transposed into a striped arrangement which is then written to memory. More...
  6. +
+
+
Usage Considerations
    +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied BlockStore::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
+
+
Examples
Example 1. Have a 128-thread threadblock directly store a blocked arrangement of four consecutive integers per thread.
#include <cub.cuh>
+
+
template <int BLOCK_THREADS>
+
__global__ void SomeKernel(int *d_out, ...)
+
{
+
// Parameterize BlockStore for the parallel execution context
+
typedef cub::BlockStore<int*, 128, 4> BlockStore;
+
+
// Declare shared memory for BlockStore
+
__shared__ typename BlockStore::SmemStorage smem_storage;
+
+
// A segment of consecutive items per thread
+
int data[4];
+
+
// Store a tile of data
+
BlockStore::Store(smem_storage, d_out + blockIdx.x * 128 * 4, data);
+
+
...
+
}
+
+

Example 2. Have a threadblock store a blocked arrangement of ITEMS_PER_THREAD consecutive integers per thread using vectorized stores and global-only caching:

+
#include <cub.cuh>
+
+
template <int BLOCK_THREADS>
+
__global__ void SomeKernel(int *d_out, ...)
+
{
+
const int ITEMS_PER_THREAD = 4;
+
+
// Parameterize BlockStore for the parallel execution context
+ +
+
// Declare shared memory for BlockStore
+
__shared__ typename BlockStore::SmemStorage smem_storage;
+
+
// A segment of consecutive items per thread
+
int data[4];
+
+
// Store a tile of data using vector-store instructions if possible
+
BlockStore::Store(smem_storage, d_out + blockIdx.x * BLOCK_THREADS * 4, data);
+
+
...
+
}
+


+

+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by BlockStore require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + +

+Static Public Methods

static __device__
+__forceinline__ void 
Store (SmemStorage &smem_storage, OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock. More...
 
template<typename SizeT >
static __device__
+__forceinline__ void 
Store (SmemStorage &smem_storage, OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock, guarded by range. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename OutputIterator , int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockStorePolicy POLICY = BLOCK_STORE_DIRECT, PtxStoreModifier MODIFIER = PTX_STORE_NONE>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >::Store (SmemStoragesmem_storage,
OutputIterator block_itr,
T(&) items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Store a tile of items across a threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]block_itrThe threadblock's base output iterator for storing to
[in]itemsData to store
+
+
+ +
+
+ +
+
+
+template<typename OutputIterator , int BLOCK_THREADS, int ITEMS_PER_THREAD, BlockStorePolicy POLICY = BLOCK_STORE_DIRECT, PtxStoreModifier MODIFIER = PTX_STORE_NONE>
+
+template<typename SizeT >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >::Store (SmemStoragesmem_storage,
OutputIterator block_itr,
const SizeT & guarded_items,
T(&) items[ITEMS_PER_THREAD] 
)
+
+inlinestatic
+
+ +

Store a tile of items across a threadblock, guarded by range.

+
Template Parameters
+ + +
SizeT[inferred] Integer type for offsets
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]block_itrThe threadblock's base output iterator for storing to
[in]guarded_itemsNumber of valid items in the tile
[in]itemsData to store
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classcub_1_1_warp_scan-members.html b/docs/html/classcub_1_1_warp_scan-members.html new file mode 100644 index 0000000000..e1dfdcb2ad --- /dev/null +++ b/docs/html/classcub_1_1_warp_scan-members.html @@ -0,0 +1,135 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS > Member List
+
+
+ +

This is the complete list of members for cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >, including all inherited members.

+ + + + + + + + + + + + + + + + + +
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >inlinestatic
SmemStorage typedefcub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >
+ + + + + diff --git a/docs/html/classcub_1_1_warp_scan.html b/docs/html/classcub_1_1_warp_scan.html new file mode 100644 index 0000000000..0d2c0b9f55 --- /dev/null +++ b/docs/html/classcub_1_1_warp_scan.html @@ -0,0 +1,1430 @@ + + + + + + + +CUB: cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS > Class Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS > Class Template Reference
+
+
+

Detailed description

+

template<typename T, int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+class cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >

+ +

WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+.
+
Overview
Given a list of input elements and a binary reduction operator, a prefix scan produces an output list where each element is computed to be the reduction of the elements occurring earlier in the input list. Prefix sum connotes a prefix scan with the addition operator. The term inclusive indicates that the ith output reduction includes the ith input. The term exclusive indicates the ith input is not computed into the ith output reduction.
+
For convenience, WarpScan exposes a spectrum of entrypoints that differ by:
    +
  • Operator (generic scan vs. prefix sum for numeric types)
  • +
  • Output ordering (inclusive vs. exclusive)
  • +
  • Warp-wide prefix (identity vs. call-back functor)
  • +
  • Output (scanned elements only vs. scanned elements and the total aggregate)
  • +
+
+
Template Parameters
+ + + + +
TThe scan input/output element type
WARPSThe number of "logical" warps performing concurrent warp scans
LOGICAL_WARP_THREADS[optional] The number of threads per "logical" warp (may be less than the number of hardware warp threads). Default is the warp size associated with the CUDA Compute Capability targeted by the compiler (e.g., 32 warps for SM20).
+
+
+
Usage Considerations
    +
  • Supports non-commutative scan operators
  • +
  • Supports "logical" warps smaller than the physical warp size (e.g., a logical warp of 8 threads)
  • +
  • Warp scans are concurrent if more than one warp is participating
  • +
  • Any warp-wide scalar inputs and outputs (e.g., warp_prefix_op and warp_aggregate) are only considered valid in lane0
  • +
  • After any operation, a subsequent __syncthreads() barrier is required if the supplied WarpScan::SmemStorage is to be reused or repurposed by the threadblock
  • +
+
+
Performance Considerations
    +
  • Uses special instructions when applicable (e.g., warp SHFL)
  • +
  • Uses synchronization-free communication between warp lanes when applicable
  • +
  • Zero bank conflicts for most types.
  • +
  • Computation is slightly more efficient (i.e., having lower instruction overhead) for:
      +
    • Prefix sum variants (vs. generic scan)
    • +
    • Exclusive variants (vs. inclusive)
    • +
    • Basic scan variants that don't require scalar inputs and outputs (e.g., warp_prefix_op and warp_aggregate)
    • +
    • Scan parameterizations where T is a built-in C++ primitive or CUDA vector type (e.g., short, int2, double, float2, etc.)
    • +
    • Scan parameterizations where LOGICAL_WARP_THREADS is a multiple of the architecture's warp size
    • +
    +
  • +
+
+
Algorithm
These parallel prefix scan variants implement a warp-synchronous Kogge-Stone algorithm having O(logn) steps and O(nlogn) work complexity, where n = LOGICAL_WARP_THREADS (which defaults to the warp size associated with the CUDA Compute Capability targeted by the compiler).
+
+
+kogge_stone_scan.png +
+
Data flow within a 16-thread Kogge-Stone scan construction. Junctions represent binary operators.

+
+
Examples
Example 1. Perform a simple exclusive prefix sum for one warp
#include <cub.cuh>
+
+
__global__ void SomeKernel(...)
+
{
+
// A parameterized int-based WarpScan type for use with one warp.
+
typedef cub::WarpScan<int, 1> WarpScan;
+
+
// Opaque shared memory for WarpScan
+
__shared__ typename WarpScan::SmemStorage smem_storage;
+
+
// Perform prefix sum of threadIds in first warp
+
if (threadIdx.x < 32)
+
{
+
int input = threadIdx.x;
+
int output;
+
WarpScan::ExclusiveSum(smem_storage, input, output);
+
+
printf("tid(%d) output(%d)\n\n", threadIdx.x, output);
+
}
+
Printed output:
tid(0) output(0)
+
tid(1) output(0)
+
tid(2) output(1)
+
tid(3) output(3)
+
tid(4) output(6)
+
...
+
tid(31) output(465)
+
+
Example 2. Perform an exclusive prefix sum for one warp seeded with a warp-wide prefix
#include <cub.cuh>
+
+
struct WarpPrefixOp
+
{
+
int warp_prefix;
+
+
__device__ WarpPrefixOp(int warp_prefix) : warp_prefix(warp_prefix) {}
+
+
__device__ int operator(int warp_aggregate)
+
{
+
int old_prefix = warp_prefix;
+
warp_prefix += warp_aggregate;
+
return old_prefix;
+
}
+
}
+
+
__global__ void SomeKernel(...)
+
{
+
// A parameterized int-based WarpScan type for use with one warp.
+
typedef cub::WarpScan<int, 1> WarpScan;
+
+
// Opaque shared memory for WarpScan
+
__shared__ typename WarpScan::SmemStorage smem_storage;
+
+
// Perform prefix sum of 2s, all seeded with a warp prefix value of 10
+
if (threadIdx.x < 32)
+
{
+
int input = 2;
+
int output;
+
int warp_aggregate;
+
WarpPrefixOp warp_prefix_op(10);
+
WarpScan::ExclusiveSum(smem_storage, input, output,
+
warp_aggregate, warp_prefix_op);
+
+
printf("tid(%d) output(%d)\n\n", threadIdx.x, output);
+
if (threadIdx.x == 0)
+
printf("updated aggregate(%d) and warp_prefix(%d)\n",
+
aggregate, warp_prefix_op.warp_prefix);
+
}
+
Printed output:
tid(0) output(10)
+
tid(1) output(12)
+
tid(2) output(14)
+
tid(3) output(16)
+
tid(4) output(18)
+
...
+
tid(31) output(72)
+
+
updated aggregate(74) and warp_prefix(84)
+
+
+ + + + +

+Public Types

+typedef _SmemStorage SmemStorage
 The operations exposed by WarpScan require shared memory of this type. This opaque storage can be allocated directly using the __shared__ keyword. Alternatively, it can be aliased to externally allocated shared memory or union'd with other types to facilitate shared memory reuse.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Methods

Inclusive prefix sums
static __device__
+__forceinline__ void 
InclusiveSum (SmemStorage &smem_storage, T input, T &output)
 Computes an inclusive prefix sum in each logical warp. More...
 
static __device__
+__forceinline__ void 
InclusiveSum (SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)
 Computes an inclusive prefix sum in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. More...
 
template<typename WarpPrefixOp >
static __device__
+__forceinline__ void 
InclusiveSum (SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)
 Computes an inclusive prefix sum in each logical warp. Instead of using 0 as the warp-wide prefix, the call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate. More...
 
Exclusive prefix sums
static __device__
+__forceinline__ void 
ExclusiveSum (SmemStorage &smem_storage, T input, T &output)
 Computes an exclusive prefix sum in each logical warp. More...
 
static __device__
+__forceinline__ void 
ExclusiveSum (SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)
 Computes an exclusive prefix sum in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. More...
 
template<typename WarpPrefixOp >
static __device__
+__forceinline__ void 
ExclusiveSum (SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)
 Computes an exclusive prefix sum in each logical warp. Instead of using 0 as the warp-wide prefix, the call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate. More...
 
Inclusive prefix scans
template<typename ScanOp >
static __device__
+__forceinline__ void 
InclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)
 Computes an inclusive prefix sum using the specified binary scan functor in each logical warp. More...
 
template<typename ScanOp >
static __device__
+__forceinline__ void 
InclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)
 Computes an inclusive prefix sum using the specified binary scan functor in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. More...
 
template<typename ScanOp , typename WarpPrefixOp >
static __device__
+__forceinline__ void 
InclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)
 Computes an inclusive prefix sum using the specified binary scan functor in each logical warp. The call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate. More...
 
Exclusive prefix scans
template<typename ScanOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. More...
 
template<typename ScanOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. More...
 
template<typename ScanOp , typename WarpPrefixOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. The call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate. More...
 
Exclusive prefix scans (without supplied identity)
template<typename ScanOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Because no identity value is supplied, the output computed for thread-lane0 is invalid. More...
 
template<typename ScanOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Because no identity value is supplied, the output computed for thread-lane0 is invalid. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. More...
 
template<typename ScanOp , typename WarpPrefixOp >
static __device__
+__forceinline__ void 
ExclusiveScan (SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)
 Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. The warp_prefix_op value from thread-thread-lane0 is applied to all scan outputs. Also computes the warp-wide warp_aggregate of all inputs for thread-thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate. More...
 
+

Member Function Documentation

+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveSum (SmemStoragesmem_storage,
input,
T & output 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum in each logical warp.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveSum (SmemStoragesmem_storage,
input,
T & output,
T & warp_aggregate 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename WarpPrefixOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveSum (SmemStoragesmem_storage,
input,
T & output,
T & warp_aggregate,
WarpPrefixOp & warp_prefix_op 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum in each logical warp. Instead of using 0 as the warp-wide prefix, the call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

The warp_prefix_op functor must implement a member function T operator()(T warp_aggregate). The functor's input parameter warp_aggregate is the same value also returned by the scan operation. This functor is expected to return a warp-wide prefix to be applied to all inputs. The functor will be invoked by the entire warp of threads, however the input and output are undefined in threads other than warp-lane0. Can be stateful.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
WarpPrefixOp[inferred] Call-back functor type having member T operator()(T warp_aggregate)
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items, exclusive of the warp_prefix_op value
[in,out]warp_prefix_op[warp-lane0 only] Call-back functor for specifying a warp-wide prefix to be applied to all inputs.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveSum (SmemStoragesmem_storage,
input,
T & output 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix sum in each logical warp.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveSum (SmemStoragesmem_storage,
input,
T & output,
T & warp_aggregate 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix sum in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename WarpPrefixOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveSum (SmemStoragesmem_storage,
input,
T & output,
T & warp_aggregate,
WarpPrefixOp & warp_prefix_op 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix sum in each logical warp. Instead of using 0 as the warp-wide prefix, the call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

The warp_prefix_op functor must implement a member function T operator()(T warp_aggregate). The functor's input parameter warp_aggregate is the same value also returned by the scan operation. This functor is expected to return a warp-wide prefix to be applied to all inputs. The functor will be invoked by the entire warp of threads, however the input and output are undefined in threads other than warp-lane0. Can be stateful.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
WarpPrefixOp[inferred] Call-back functor type having member T operator()(T warp_aggregate)
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items (exclusive of the warp_prefix_op value).
[in,out]warp_prefix_op[warp-lane0 only] Call-back functor for specifying a warp-wide prefix to be applied to all inputs.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum using the specified binary scan functor in each logical warp.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op,
T & warp_aggregate 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum using the specified binary scan functor in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp , typename WarpPrefixOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::InclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op,
T & warp_aggregate,
WarpPrefixOp & warp_prefix_op 
)
+
+inlinestatic
+
+ +

Computes an inclusive prefix sum using the specified binary scan functor in each logical warp. The call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

The warp_prefix_op functor must implement a member function T operator()(T warp_aggregate). The functor's input parameter warp_aggregate is the same value also returned by the scan operation. This functor is expected to return a warp-wide prefix to be applied to all inputs. The functor will be invoked by the entire warp of threads, however the input and output are undefined in threads other than warp-lane0. Can be stateful.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
WarpPrefixOp[inferred] Call-back functor type having member T operator()(T warp_aggregate)
+
+
+
Parameters
+ + + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items (exclusive of the warp_prefix_op value).
[in,out]warp_prefix_op[warp-lane0 only] Call-back functor for specifying a warp-wide prefix to be applied to all inputs.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
const T & identity,
ScanOp scan_op 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]identityIdentity value
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
const T & identity,
ScanOp scan_op,
T & warp_aggregate 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]identityIdentity value
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp , typename WarpPrefixOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
const T & identity,
ScanOp scan_op,
T & warp_aggregate,
WarpPrefixOp & warp_prefix_op 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. The call-back functor warp_prefix_op is invoked to provide the "seed" value that logically prefixes the warp's scan inputs. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

The warp_prefix_op functor must implement a member function T operator()(T warp_aggregate). The functor's input parameter warp_aggregate is the same value also returned by the scan operation. This functor is expected to return a warp-wide prefix to be applied to all inputs. The functor will be invoked by the entire warp of threads, however the input and output are undefined in threads other than warp-lane0. Can be stateful.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
WarpPrefixOp[inferred] Call-back functor type having member T operator()(T warp_aggregate)
+
+
+
Parameters
+ + + + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]identityIdentity value
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items (exclusive of the warp_prefix_op value).
[in,out]warp_prefix_op[warp-lane0 only] Call-back functor for specifying a warp-wide prefix to be applied to all inputs.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Because no identity value is supplied, the output computed for thread-lane0 is invalid.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op,
T & warp_aggregate 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. Because no identity value is supplied, the output computed for thread-lane0 is invalid. Also computes the warp-wide warp_aggregate of all inputs for thread-lane0.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
+
+
+
Parameters
+ + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items.
+
+
+ +
+
+ +
+
+
+template<typename T , int WARPS, int LOGICAL_WARP_THREADS = DeviceProps::WARP_THREADS>
+
+template<typename ScanOp , typename WarpPrefixOp >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static __device__ __forceinline__ void cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >::ExclusiveScan (SmemStoragesmem_storage,
input,
T & output,
ScanOp scan_op,
T & warp_aggregate,
WarpPrefixOp & warp_prefix_op 
)
+
+inlinestatic
+
+ +

Computes an exclusive prefix scan using the specified binary scan functor in each logical warp. The warp_prefix_op value from thread-thread-lane0 is applied to all scan outputs. Also computes the warp-wide warp_aggregate of all inputs for thread-thread-lane0. The warp_prefix_op is further updated by the value of warp_aggregate.

+

The warp_aggregate is undefined in threads other than thread-lane0.

+

The warp_prefix_op functor must implement a member function T operator()(T warp_aggregate). The functor's input parameter warp_aggregate is the same value also returned by the scan operation. This functor is expected to return a warp-wide prefix to be applied to all inputs. The functor will be invoked by the entire warp of threads, however the input and output are undefined in threads other than warp-lane0. Can be stateful.

+

A subsequent __syncthreads() threadblock barrier should be invoked after calling this method if the supplied smem_storage is to be reused or repurposed by the threadblock.

+
Template Parameters
+ + + +
ScanOp[inferred] Binary scan operator type having member T operator()(const T &a, const T &b)
WarpPrefixOp[inferred] Call-back functor type having member T operator()(T warp_aggregate)
+
+
+
Parameters
+ + + + + + + +
[in]smem_storageShared reference to opaque SmemStorage layout
[in]inputCalling thread's input item.
[out]outputCalling thread's output item. May be aliased with input.
[in]scan_opBinary scan operator having member T operator()(const T &a, const T &b)
[out]warp_aggregate[warp-lane0 only] Warp-wide aggregate reduction of input items (exclusive of the warp_prefix_op value).
[in,out]warp_prefix_op[warp-lane0 only] Call-back functor for specifying a warp-wide prefix to be applied to all inputs.
+
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + + diff --git a/docs/html/classes.html b/docs/html/classes.html new file mode 100644 index 0000000000..4281200122 --- /dev/null +++ b/docs/html/classes.html @@ -0,0 +1,138 @@ + + + + + + + +CUB: Class Index + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Index
+
+
+
A | B | E | I | L | M | N | R | S | T | W
+ + + + + + + + + + + + +
  A  
+
BlockRadixSort (cub)   
  I  
+
  N  
+
  T  
+
BlockReduce (cub)   
ArrayTraits (cub)   BlockScan (cub)   If (cub)   NullType (cub)   Traits (cub)   
  B  
+
BlockStore (cub)   IsVolatile (cub)   NumericTraits (cub)   
  W  
+
  E  
+
  L  
+
  R  
+
BaseTraits (cub)   WarpScan (cub)   
BlockDiscontinuity (cub)   EnableIf (cub)   Log2 (cub)   RemoveQualifiers (cub)   
BlockExchange (cub)   Equality (cub)   
  M  
+
  S  
+
BlockLoad (cub)   Equals (cub)   
Max (cub)   Sum (cub)   
+
A | B | E | I | L | M | N | R | S | T | W
+
+ + + + + diff --git a/docs/html/closed.png b/docs/html/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/cub/docs/images/cub_overview.png b/docs/html/cub_overview.png similarity index 100% rename from cub/docs/images/cub_overview.png rename to docs/html/cub_overview.png diff --git a/docs/html/debug_8cuh.html b/docs/html/debug_8cuh.html new file mode 100644 index 0000000000..de86308386 --- /dev/null +++ b/docs/html/debug_8cuh.html @@ -0,0 +1,177 @@ + + + + + + + +CUB: debug.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
debug.cuh File Reference
+
+
+
#include <stdio.h>
+#include "ns_wrapper.cuh"
+#include "device_props.cuh"
+
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + + +

+Macros

#define CubDebug(f)   cub::Debug(f, __FILE__, __LINE__)
 
#define CubDebugExit(f)   if (cub::Debug(f, __FILE__, __LINE__)) exit(1)
 
+ + + + + + + +

+Functions

__host__ __device__
+__forceinline__ cudaError_t 
cub::Debug (cudaError_t error, const char *message, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, message is printed to stderr along with the supplied source context. More...
 
__host__ __device__
+__forceinline__ cudaError_t 
cub::Debug (cudaError_t error, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, the corresponding error message is printed to stderr along with the supplied source context. More...
 
+

Detailed Description

+

Debug error display routines

+

Macro Definition Documentation

+ +
+
+ + + + + + + + +
#define CubDebug( f)   cub::Debug(f, __FILE__, __LINE__)
+
+

Debug macro

+ +
+
+ +
+
+ + + + + + + + +
#define CubDebugExit( f)   if (cub::Debug(f, __FILE__, __LINE__)) exit(1)
+
+

Debug macro with exit

+ +
+
+
+ + + + + diff --git a/cub/docs/images/devfun_abstraction.png b/docs/html/devfun_abstraction.png similarity index 100% rename from cub/docs/images/devfun_abstraction.png rename to docs/html/devfun_abstraction.png diff --git a/docs/html/dir_011e1c944d88f71be72e1e24a5fda7cf.html b/docs/html/dir_011e1c944d88f71be72e1e24a5fda7cf.html new file mode 100644 index 0000000000..208be39297 --- /dev/null +++ b/docs/html/dir_011e1c944d88f71be72e1e24a5fda7cf.html @@ -0,0 +1,126 @@ + + + + + + + +CUB: block Directory Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
block Directory Reference
+
+
+ + + + + + + + + + + + + + + + +

+Files

file  block_discontinuity.cuh
 
file  block_exchange.cuh
 
file  block_load.cuh
 
file  block_radix_sort.cuh
 
file  block_reduce.cuh
 
file  block_scan.cuh
 
file  block_store.cuh
 
+
+ + + + + diff --git a/docs/html/dir_bb50a5ef59f19d030d06415663184d05.html b/docs/html/dir_bb50a5ef59f19d030d06415663184d05.html new file mode 100644 index 0000000000..856cb7cfae --- /dev/null +++ b/docs/html/dir_bb50a5ef59f19d030d06415663184d05.html @@ -0,0 +1,116 @@ + + + + + + + +CUB: thread Directory Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
thread Directory Reference
+
+
+ + + + + + +

+Files

file  thread_load.cuh
 
file  thread_store.cuh
 
+
+ + + + + diff --git a/docs/html/dir_cb3a671affffe7eeb3fdf5ae58e42cc8.html b/docs/html/dir_cb3a671affffe7eeb3fdf5ae58e42cc8.html new file mode 100644 index 0000000000..fdafbaa2e6 --- /dev/null +++ b/docs/html/dir_cb3a671affffe7eeb3fdf5ae58e42cc8.html @@ -0,0 +1,114 @@ + + + + + + + +CUB: warp Directory Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
warp Directory Reference
+
+
+ + + + +

+Files

file  warp_scan.cuh
 
+
+ + + + + diff --git a/docs/html/dir_d583f216f1aafe19404e836b0c097ad2.html b/docs/html/dir_d583f216f1aafe19404e836b0c097ad2.html new file mode 100644 index 0000000000..47f004ecdc --- /dev/null +++ b/docs/html/dir_d583f216f1aafe19404e836b0c097ad2.html @@ -0,0 +1,127 @@ + + + + + + + +CUB: cub Directory Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
cub Directory Reference
+
+
+ + + + + + + + +

+Directories

directory  block
 
directory  thread
 
directory  warp
 
+ + + + + + + +

+Files

file  debug.cuh
 
file  operators.cuh
 
file  type_utils.cuh
 
+
+ + + + + diff --git a/cub/docs/images/discont_logo.png b/docs/html/discont_logo.png similarity index 100% rename from cub/docs/images/discont_logo.png rename to docs/html/discont_logo.png diff --git a/cub/docs/images/download-icon.png b/docs/html/download-icon.png similarity index 100% rename from cub/docs/images/download-icon.png rename to docs/html/download-icon.png diff --git a/docs/html/download_cub.html b/docs/html/download_cub.html new file mode 100644 index 0000000000..5fe0be4517 --- /dev/null +++ b/docs/html/download_cub.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + +
+If your download doesn't start in 3s: +

+ +Download CUB! +
+ + + \ No newline at end of file diff --git a/docs/html/doxygen.css b/docs/html/doxygen.css new file mode 100644 index 0000000000..dabaff2fd8 --- /dev/null +++ b/docs/html/doxygen.css @@ -0,0 +1,1184 @@ +/* The standard CSS for doxygen 1.8.3.1 */ + +body, table, div, p, dl { + font: 400 14px/19px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px; + margin: 4px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view when not used as main index */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 5px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 2px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/docs/html/doxygen.png b/docs/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 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 literal 0 HcmV?d00001 diff --git a/docs/html/dynsections.js b/docs/html/dynsections.js new file mode 100644 index 0000000000..ed092c7f63 --- /dev/null +++ b/docs/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} +function toggleLevel(level) +{ + $('table.directory tr').each(function(){ + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (ldjv*C{Z|`mdau^P8_z}#X h?B8GEpdi4(BFDx$je&7RrDQEg&ePS;Wt~$(69Dh@6T1Ka literal 0 HcmV?d00001 diff --git a/docs/html/ftv2cl.png b/docs/html/ftv2cl.png new file mode 100644 index 0000000000000000000000000000000000000000..132f6577bf7f085344904602815a260d29f55d9b GIT binary patch literal 453 zcmV;$0XqJPP)VBF;ev;toEj8_OB0EQg5eYilIj#JZG_m^33l3^k4mtzx!TVD?g)Y$ zrvwRDSqT!wLIM$dWCIa$vtxE|mzbTzu-y&$FvF6WA2a{Wr1g}`WdPT-0JzEZ0IxAv z-Z+ejZc&H;I5-pb_SUB}04j0^V)3t{`z<7asDl2Tw3w3sP%)0^8$bhEg)IOTBcRXv zFfq~3&gvJ$F-U7mpBW8z1GY~HK&7h4^YI~Orv~wLnC0PP_dAkv;nzX{9Q|8Gv=2ca z@v)c9T;D#h`TZ2X&&$ff2wedmot995de~-s3I)yauahg;7qn*?1n?F$e+PwP37}~; z1NKUk7reVK^7A;$QRW7qAx40HHUZ<|k3U%nz(Ec`#i+q9K!dgcROAlCS?`L= v>#=f?wF5ZND!1uAfQsk;KN^4&*8~0npJiJ%2dj9(00000NkvXXu0mjfWVFf_ literal 0 HcmV?d00001 diff --git a/docs/html/ftv2doc.png b/docs/html/ftv2doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/docs/html/ftv2folderclosed.png b/docs/html/ftv2folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/docs/html/ftv2lastnode.png b/docs/html/ftv2lastnode.png new file mode 100644 index 0000000000000000000000000000000000000000..63c605bb4c3d941c921a4b6cfa74951e946bcb48 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRr!3HExu9B$%QnH>djv*C{Z|`mdau^P8_z}#X h?B8GEpdi4(BFDx$je&7RrDQEg&ePS;Wt~$(69Dh@6T1Ka literal 0 HcmV?d00001 diff --git a/docs/html/ftv2link.png b/docs/html/ftv2link.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/docs/html/ftv2mlastnode.png b/docs/html/ftv2mlastnode.png new file mode 100644 index 0000000000000000000000000000000000000000..0b63f6d38c4b9ec907b820192ebe9724ed6eca22 GIT binary patch literal 246 zcmVkw!R34#Lv2LOS^S2tZA31X++9RY}n zChwn@Z)Wz*WWHH{)HDtJnq&A2hk$b-y(>?@z0iHr41EKCGp#T5?07*qoM6N<$f(V3Pvj6}9 literal 0 HcmV?d00001 diff --git a/docs/html/ftv2mnode.png b/docs/html/ftv2mnode.png new file mode 100644 index 0000000000000000000000000000000000000000..0b63f6d38c4b9ec907b820192ebe9724ed6eca22 GIT binary patch literal 246 zcmVkw!R34#Lv2LOS^S2tZA31X++9RY}n zChwn@Z)Wz*WWHH{)HDtJnq&A2hk$b-y(>?@z0iHr41EKCGp#T5?07*qoM6N<$f(V3Pvj6}9 literal 0 HcmV?d00001 diff --git a/docs/html/ftv2mo.png b/docs/html/ftv2mo.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfb80f76e65815989a9350ad79d8ce45380e2b1 GIT binary patch literal 403 zcmV;E0c`$>P)${!fXv7NWJ%@%u4(KapRY>T6_x;E zxE7kt!}Tiw8@d9Sd`rTGum>z#Q14vIm`wm1#-byD1muMi02@YNO5LRF0o!Y{`a!Ya z{^&p0Su|s705&2QxmqdexG+-zNKL3f@8gTQSJrKByfo+oNJ^-{|Mn||Q5SDwjQVsS zr1}7o5-QMs>gYIMD>GRw@$lT`z4r-_m{5U#cR{urD_)TOeY)(UD|qZ^&y`IVijqk~ xs(9-kWFr7E^!lgi8GsFK5kOY_{Xbgf0^etEU%fLevs?fG002ovPDHLkV1nB&vX1}& literal 0 HcmV?d00001 diff --git a/docs/html/ftv2node.png b/docs/html/ftv2node.png new file mode 100644 index 0000000000000000000000000000000000000000..63c605bb4c3d941c921a4b6cfa74951e946bcb48 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRr!3HExu9B$%QnH>djv*C{Z|`mdau^P8_z}#X h?B8GEpdi4(BFDx$je&7RrDQEg&ePS;Wt~$(69Dh@6T1Ka literal 0 HcmV?d00001 diff --git a/docs/html/ftv2ns.png b/docs/html/ftv2ns.png new file mode 100644 index 0000000000000000000000000000000000000000..72e3d71c2892d6f00e259facebc88b45f6db2e35 GIT binary patch literal 388 zcmV-~0ek+5P)f+++#cT|!CkD&4pnIkeMEUEM*>`*9>+Juji$!h-mW%M^8s9957{3nvbrz^&=u<~TAUrFROkmt%^F~Ez+-c53Lv%iH3d38!Rv?K zrb&MYAhp;Gf<}wS;9ZZq2@;!uYG;=Z>~GKE^{HD4keu}lnyqhc>kWX^tQn|warJ~h zT+rtMkdz6aHoN%z(o|&wpu@@OpJnF_z{PA)6(FHw02iHslz^(N{4*+K9)QJHR87wT iTyp>aXaF{u2lxRou|^4tux6eB0000^P)R?RzRoKvklcaQ%HF6%rK2&ZgO(-ihJ_C zzrKgp4jgO( fd_(yg|3PpEQb#9`a?Pz_00000NkvXXu0mjftR`5K literal 0 HcmV?d00001 diff --git a/docs/html/ftv2pnode.png b/docs/html/ftv2pnode.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ee22f937a07d1dbfc27c669d11f8ed13e2f152 GIT binary patch literal 229 zcmV^P)R?RzRoKvklcaQ%HF6%rK2&ZgO(-ihJ_C zzrKgp4jgO( fd_(yg|3PpEQb#9`a?Pz_00000NkvXXu0mjftR`5K literal 0 HcmV?d00001 diff --git a/docs/html/ftv2splitbar.png b/docs/html/ftv2splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/docs/html/ftv2vertline.png b/docs/html/ftv2vertline.png new file mode 100644 index 0000000000000000000000000000000000000000..63c605bb4c3d941c921a4b6cfa74951e946bcb48 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRr!3HExu9B$%QnH>djv*C{Z|`mdau^P8_z}#X h?B8GEpdi4(BFDx$je&7RrDQEg&ePS;Wt~$(69Dh@6T1Ka literal 0 HcmV?d00001 diff --git a/docs/html/functions.html b/docs/html/functions.html new file mode 100644 index 0000000000..82d31affeb --- /dev/null +++ b/docs/html/functions.html @@ -0,0 +1,267 @@ + + + + + + + +CUB: Class Members + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- f -

+ + +

- i -

+ + +

- l -

+ + +

- o -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- v -

+
+ + + + + diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html new file mode 100644 index 0000000000..c13f0d5f36 --- /dev/null +++ b/docs/html/functions_func.html @@ -0,0 +1,231 @@ + + + + + + + +CUB: Class Members - Functions + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- b -

+ + +

- e -

+ + +

- f -

+ + +

- i -

+ + +

- l -

+ + +

- o -

+ + +

- r -

+ + +

- s -

+
+ + + + + diff --git a/docs/html/functions_type.html b/docs/html/functions_type.html new file mode 100644 index 0000000000..3b7a665c1d --- /dev/null +++ b/docs/html/functions_type.html @@ -0,0 +1,133 @@ + + + + + + + +CUB: Class Members - Typedefs + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + +
+ + + + +
+ +
+ + + + + + + diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html new file mode 100644 index 0000000000..22fc0f82cb --- /dev/null +++ b/docs/html/functions_vars.html @@ -0,0 +1,124 @@ + + + + + + + +CUB: Class Members - Variables + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + +
+ + + + +
+ +
+ + + + + + + diff --git a/cub/docs/images/github-icon-747d8b799a48162434b2c0595ba1317e.png b/docs/html/github-icon-747d8b799a48162434b2c0595ba1317e.png similarity index 100% rename from cub/docs/images/github-icon-747d8b799a48162434b2c0595ba1317e.png rename to docs/html/github-icon-747d8b799a48162434b2c0595ba1317e.png diff --git a/docs/html/group___host_util.html b/docs/html/group___host_util.html new file mode 100644 index 0000000000..94588d9949 --- /dev/null +++ b/docs/html/group___host_util.html @@ -0,0 +1,195 @@ + + + + + + + +CUB: Host Utilities + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + +
+ + + + +
+ +
+ +
+ +
+
Host Utilities
+
+
+ + + + + + + + +

+Functions

__host__ __device__
+__forceinline__ cudaError_t 
cub::Debug (cudaError_t error, const char *message, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, message is printed to stderr along with the supplied source context. More...
 
__host__ __device__
+__forceinline__ cudaError_t 
cub::Debug (cudaError_t error, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, the corresponding error message is printed to stderr along with the supplied source context. More...
 
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
__host__ __device__ __forceinline__ cudaError_t cub::Debug (cudaError_t error,
const char * message,
const char * filename,
int line 
)
+
+ +

If CUB_STDERR is defined and error is not cudaSuccess, message is printed to stderr along with the supplied source context.

+
Returns
The CUDA error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
__host__ __device__ __forceinline__ cudaError_t cub::Debug (cudaError_t error,
const char * filename,
int line 
)
+
+ +

If CUB_STDERR is defined and error is not cudaSuccess, the corresponding error message is printed to stderr along with the supplied source context.

+
Returns
The CUDA error.
+ +
+
+
+ + + + + diff --git a/docs/html/group___simt.html b/docs/html/group___simt.html new file mode 100644 index 0000000000..bff7bac5d7 --- /dev/null +++ b/docs/html/group___simt.html @@ -0,0 +1,114 @@ + + + + + + + +CUB: SIMT Primitives + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + +
+ + + + +
+ +
+ +
+ +
+
SIMT Primitives
+
+
+ + + + + + +

+Modules

 Cooperative SIMT Operations
 
 SIMT Utilities
 
+
+ + + + + diff --git a/docs/html/group___simt_coop.html b/docs/html/group___simt_coop.html new file mode 100644 index 0000000000..c26e678565 --- /dev/null +++ b/docs/html/group___simt_coop.html @@ -0,0 +1,174 @@ + + + + + + + +CUB: Cooperative SIMT Operations + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + +
+ + + + +
+ +
+ +
+ +
+
Cooperative SIMT Operations
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

class  cub::BlockDiscontinuity< T, BLOCK_THREADS >
 BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+.
+ More...
 
class  cub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >
 BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+.
+ More...
 
class  cub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
 BlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+.
+ More...
 
class  cub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >
 BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+.
+ More...
 
class  cub::BlockReduce< T, BLOCK_THREADS >
 BlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+.
+ More...
 
class  cub::BlockScan< T, BLOCK_THREADS, POLICY >
 BlockScan provides variants of parallel prefix scan (and prefix sum) across a CUDA threadblock.

+
+scan_logo.png +
+.
+ More...
 
class  cub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >
 BlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+.
+ More...
 
class  cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >
 WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+.
+ More...
 
+
+ + + + + diff --git a/docs/html/group___simt_utils.html.REMOVED.git-id b/docs/html/group___simt_utils.html.REMOVED.git-id new file mode 100644 index 0000000000..a0d067bf82 --- /dev/null +++ b/docs/html/group___simt_utils.html.REMOVED.git-id @@ -0,0 +1 @@ +4f12ad3881281ec2783eca35eaee8cc6a3c7413e \ No newline at end of file diff --git a/cub/docs/images/groups-icon.png b/docs/html/groups-icon.png similarity index 100% rename from cub/docs/images/groups-icon.png rename to docs/html/groups-icon.png diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html new file mode 100644 index 0000000000..c4f3a5d277 --- /dev/null +++ b/docs/html/hierarchy.html @@ -0,0 +1,173 @@ + + + + + + + +CUB: Class Hierarchy + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + +
oCcub::ArrayTraits< ArrayType, LENGTH >Array traits
oCcub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits >Basic type traits
oCcub::BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type >
|\Ccub::NumericTraits< RemoveQualifiers< T >::Type >
| \Ccub::Traits< T >Type traits
oCcub::BaseTraits< NOT_A_NUMBER, false, false, T >
|\Ccub::NumericTraits< T >Numeric type traits
oCcub::BlockDiscontinuity< T, BLOCK_THREADS >BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+
oCcub::BlockExchange< T, BLOCK_THREADS, ITEMS_PER_THREAD >BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+
oCcub::BlockLoad< InputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >BlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+
oCcub::BlockRadixSort< KeyType, BLOCK_THREADS, ITEMS_PER_THREAD, ValueType, RADIX_BITS, SMEM_CONFIG >BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+
oCcub::BlockReduce< T, BLOCK_THREADS >BlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+
oCcub::BlockScan< T, BLOCK_THREADS, POLICY >BlockScan provides variants of parallel prefix scan (and prefix sum) across a CUDA threadblock.

+
+scan_logo.png +
+
oCcub::BlockStore< OutputIterator, BLOCK_THREADS, ITEMS_PER_THREAD, POLICY, MODIFIER >BlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+
oCcub::EnableIf< Condition, T >Simple enable-if (similar to Boost)
oCcub::Equality< T >Default equality functor
oCcub::Equals< A, B >Type equality test
oCcub::If< IF, ThenType, ElseType >Type selection (IF ? ThenType : ElseType)
oCcub::IsVolatile< Tp >Volatile modifier test
oCcub::Log2< N, CURRENT_VAL, COUNT >Statically determine log2(N), rounded up
oCcub::Max< T >Default max functor
oCcub::NullTypeA simple "NULL" marker type
oCcub::RemoveQualifiers< Tp, Up >Removes const and volatile qualifiers from type Tp
oCcub::Sum< T >Default sum functor
\Ccub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+
+
+
+ + + + + diff --git a/docs/html/index.html b/docs/html/index.html new file mode 100644 index 0000000000..67e3ff65b9 --- /dev/null +++ b/docs/html/index.html @@ -0,0 +1,358 @@ + + + + + + + +CUB: Main Page + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + +
+ + + + +
+ +
+ +
+
+
CUB Documentation
+
+
+ +
+ +   +Download CUB! +
+ +   +Browse or fork CUB at GitHub! +
+ +   +Join the cub-users discussion forum! +

+(1) What is CUB?

+
CUB is a library of high-performance parallel primitives and other utilities for constructing CUDA kernel software. CUB enhances productivity, performance, and portability by providing an abstraction layer over complex block-level, warp-level, and thread-level operations.
+
CUB's primitives are not bound to any particular width of parallelism or to any particular data type. This allows them to be flexible and tunable to fit your kernels' needs. Thus CUB is CUDA Unbound.
+
+cub_overview.png +
+
Browse our collections of:
    +
  • Cooperative primitives, including:
      +
    • Thread block operations (e.g., radix sort, prefix scan, reduction, etc.)
    • +
    • Warp operations (e.g., prefix scan)
    • +
    +
  • +
  • SIMT utilities, including:
      +
    • Tile-based I/O utilities (e.g., for performing {vectorized, coalesced} data movement of {blocked, striped} data tiles)
    • +
    • Low-level thread I/O using cache-modifiers
    • +
    • Abstractions for thread block work distribution (e.g., work-stealing, even-share, etc.)
    • +
    +
  • +
  • Host utilities, including:
      +
    • Caching allocator for quick management of device temporaries
    • +
    • Device reflection
    • +
    +
  • +
+
+

+(2) Recent news

+
    +
  • CUB v0.9.1 (03/09/2013). Intial "preview" release. CUB is the first durable, high-performance library of cooperative block-level, warp-level, and thread-level primitives for CUDA kernel programming. More primitives and examples coming soon!
  • +
+
+

+(3) A simple example

+
The following code snippet illustrates a simple CUDA kernel for sorting a thread block's data:
+
#include <cub.cuh>
+
+
// An tile-sorting CUDA kernel
+
template <
+
int BLOCK_THREADS, // Threads per block
+
int ITEMS_PER_THREAD, // Items per thread
+
typename T> // Numeric data type
+
__global__ void TileSortKernel(T *d_in, T *d_out)
+
{
+
using namespace cub;
+
const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD;
+
+
// Parameterize cub::BlockRadixSort for the parallel execution context
+
typedef BlockRadixSort<T, BLOCK_THREADS> BlockRadixSort;
+
+
// Declare the shared memory needed by BlockRadixSort
+
__shared__ typename BlockRadixSort::SmemStorage smem_storage;
+
+
// A segment of data items per thread
+
T data[ITEMS_PER_THREAD];
+
+
// Load a tile of data using vector-load instructions
+
BlockLoadVectorized(data, d_in + (blockIdx.x * TILE_SIZE));
+
+
// Sort data in ascending order
+
BlockRadixSort::SortBlocked(smem_storage, data);
+
+
// Store the sorted tile using vector-store instructions
+
BlockStoreVectorized(data, d_out + (blockIdx.x * TILE_SIZE));
+
}
+
+
The cub::BlockRadixSort type performs a cooperative radix sort across the thread block's data items. Its implementation is parameterized by the number of threads per block and the aggregate data type T and is specialized for the underlying architecture.
+
Once instantiated, the cub::BlockRadixSort type exposes an opaque cub::BlockRadixSort::SmemStorage member type. The thread block uses this storage type to allocate the shared memory needed by the primitive. This storage type can be aliased or union'd with other types so that the shared memory can be reused for other purposes.
+
Furthermore, the kernel uses CUB's primitives for vectorizing global loads and stores. For example, lower-level ld.global.v4.s32 PTX instructions will be generated when T = int and ITEMS_PER_THREAD is a multiple of 4.
+

+(4) Why do you need CUB?

+
CUDA kernel software is where the complexity of parallelism is expressed. Programmers must reason about deadlock, livelock, synchronization, race conditions, shared memory layout, plurality of state, granularity, throughput, latency, memory bottlenecks, etc. Constructing and fine-tuning kernel code is perhaps the most challenging, time-consuming aspect of CUDA programming.
+
However, with the exception of CUB, there are few (if any) software libraries of reusable kernel primitives. In the CUDA ecosystem, CUB is unique in this regard. As a SIMT library and software abstraction layer, CUB provides:
    +
  1. Simplicity of composition. Parallel CUB primitives can be simply sequenced together in kernel code. (This convenience is analogous to programming with Thrust primitives in the host program.)
  2. +
  3. High performance. CUB simplifies high performance kernel development by taking care to implement and make available the fastest available algorithms, strategies, and techniques.
  4. +
  5. Performance portability. CUB primitives are specialized to match the target hardware. Furthermore, the CUB library continually evolves to accommodate new algorithmic developments, hardware instructions, etc.
  6. +
  7. Simplicity of performance tuning. CUB primitives provide parallel abstractions whose performance behavior can be statically tuned. For example, most CUB primitives support alternative algorithmic strategies and variable grain sizes (threads per block, items per thread, etc.).
  8. +
  9. Robustness and durability. CUB primitives are designed to function properly for arbitrary data types and widths of parallelism (not just for the built-in C++ types or for powers-of-two threads per block).
  10. +
+
+

+(5) Where is CUB positioned in the CUDA ecosystem?

+
CUDA's programming model embodies three different levels of program execution, each engendering its own abstraction layer in the CUDA software stack (i.e., the "black boxes" below):
+ + + + + + + +
CUDA kernel. A single CPU thread invokes a CUDA kernel to perform some data-parallel function. The incorporation of entire kernels (and their corresponding invocation stubs) into libraries is the most common form of code reuse for CUDA. Libraries of CUDA kernels include the following: +
+
+ +
Thread blocks (SIMT). Each kernel invocation comprises some number of parallel threads. Threads are grouped into blocks, and the entire block of threads invokes some cooperative function in which they communicate and synchronize with each other. There has historically been very little reuse of cooperative SIMT software within CUDA kernel. Libraries of thread-block primitives include the following: +
+
+ +
CUDA thread. A single CUDA thread invokes some sequential function. This is the finest-grained level of CUDA software abstraction and requires no consideration for the scheduling or synchronization of parallel threads. CUDA libraries of purely data-parallel functions include the following: +
+
+ +
+

+(6) How does CUB work?

+
CUB leverages the following programming idioms:
    +
  1. C++ templates
  2. +
  3. Reflective type structure
  4. +
  5. Flexible data mapping
  6. +
+
+

+6.1    C++ templates

+
As a SIMT library, CUB must be flexible enough to accommodate a wide spectrum of parallel execution contexts, i.e., specific:
    +
  • Data types
  • +
  • Widths of parallelism (threads per block)
  • +
  • Grain sizes (data items per thread)
  • +
  • Underlying architectures (special instructions, warp size, rules for bank conflicts, etc.)
  • +
  • Tuning requirements (e.g., latency vs. throughput)
  • +
+
+
To provide this flexibility, CUB is implemented as a C++ template library. C++ templates are a way to write generic algorithms and data structures. There is no need to build CUB separately. You simply #include the cub.cuh header file into your .cu CUDA C++ sources and compile with NVIDIA's nvcc compiler.
+

+6.2    Reflective type structure

+
Cooperation within a thread block requires shared memory for communicating between threads. However, the specific size and layout of the memory needed by a given primitive will be specific to the details of its parallel execution context (e.g., how many threads are calling into it, how many items are processed per thread, etc.). Furthermore, this shared memory must be allocated outside of the component itself if it is to be reused elsewhere by the thread block.
+
// Parameterize a BlockScan type for use with 128 threads
+
// and 4 items per thread
+ +
+
// Declare shared memory for BlockScan
+
__shared__ typename BlockScan::SmemStorage smem_storage;
+
+
// A segment of consecutive input items per thread
+
int data[4];
+
+
// Obtain data in blocked order
+
...
+
+
// Perform an exclusive prefix sum across the tile of data
+
BlockScan::ExclusiveSum(smem_storage, data, data);
+
+
To address this issue, we encapsulate cooperative procedures within reflective type structure (C++ classes). As illustrated in the cub::BlockScan example above, these primitives are C++ classes with interfaces that expose both:
    +
  • Procedural entrypoints for a block of threads to invoke
  • +
  • An opaque shared memory type needed for the operation of those methods
  • +
+
+

+6.3    Flexible data mapping

+
We often design kernels such that each thread block is assigned a "tile" of data items for processing.
+
+tile.png +
+
Tile of eight ordered data items
+
When the tile size equals the thread block size, the mapping of data onto threads is straightforward (one datum per thread). However, there are often performance advantages for processing more than one datum per thread. For these scenarios, CUB primitives support the following alternatives for partitioning data items across the block of threads:
+ + + + + +
    +
  • Blocked arrangement. The aggregate tile of items is partitioned evenly across threads in "blocked" fashion with threadi owning the ith segment of consecutive elements. Blocked arrangements are often desirable for algorithmic benefits (where long sequences of items can be processed sequentially within each thread).
  • +
+
+
+blocked.png +
+
Blocked arrangement across four threads
+(emphasis on items owned by thread0)
+
    +
  • Striped arrangement. The aggregate tile of items is partitioned across threads in "striped" fashion, i.e., the ITEMS_PER_THREAD items owned by each thread have logical stride BLOCK_THREADS between them. Striped arrangements are often desirable for data movement through global memory (where read/write coalescing is an important performance consideration).
  • +
+
+
+striped.png +
+
Striped arrangement across four threads
+(emphasis on items owned by thread0)
+
+
The benefits of processing multiple items per thread (a.k.a., register blocking, granularity coarsening, etc.) include:
    +
  • Algorithmic efficiency. Sequential work over multiple items in thread-private registers is cheaper than synchronized, cooperative work through shared memory spaces.
  • +
  • Data occupancy. The number of items that can be resident on-chip in thread-private register storage is often greater than the number of schedulable threads.
  • +
  • Instruction-level parallelism. Multiple items per thread also facilitates greater ILP for improved throughput and utilization.
  • +
+
+
Finally, cub::BlockExchange provides operations for converting between blocked and striped arrangements.
+

+(7) Contributors

+
CUB is developed as an open-source project by NVIDIA Research. The primary contributor is Duane Merrill.
+

+(8) Open Source License

+
CUB is available under the "New BSD" open-source license:
+
Copyright (c) 2011, Duane Merrill. All rights reserved.
+
Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
+
+
Redistribution and use in source and binary forms, with or without
+
modification, are permitted provided that the following conditions are met:
+
* Redistributions of source code must retain the above copyright
+
notice, this list of conditions and the following disclaimer.
+
* Redistributions in binary form must reproduce the above copyright
+
notice, this list of conditions and the following disclaimer in the
+
documentation and/or other materials provided with the distribution.
+
* Neither the name of the NVIDIA CORPORATION nor the
+
names of its contributors may be used to endorse or promote products
+
derived from this software without specific prior written permission.
+
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+
DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ + + + + diff --git a/docs/html/jquery.js b/docs/html/jquery.js new file mode 100644 index 0000000000..63939e76dd --- /dev/null +++ b/docs/html/jquery.js @@ -0,0 +1,8 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")), +f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c) +{if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); diff --git a/cub/docs/images/kernel_abstraction.png b/docs/html/kernel_abstraction.png similarity index 100% rename from cub/docs/images/kernel_abstraction.png rename to docs/html/kernel_abstraction.png diff --git a/cub/docs/images/kogge_stone_scan.png b/docs/html/kogge_stone_scan.png similarity index 100% rename from cub/docs/images/kogge_stone_scan.png rename to docs/html/kogge_stone_scan.png diff --git a/docs/html/modules.html b/docs/html/modules.html new file mode 100644 index 0000000000..f36812ffd6 --- /dev/null +++ b/docs/html/modules.html @@ -0,0 +1,112 @@ + + + + + + + +CUB: Modules + + + + + + + + + + + + +
+
+
+ + + + + +
+
CUB +
+
+ + + + + + + + + + +
+ +
+ +
+
+
Modules
+
+
+
Here is a list of all modules:
+
+ + + + + diff --git a/docs/html/namespacecub.html b/docs/html/namespacecub.html new file mode 100644 index 0000000000..af535a48ed --- /dev/null +++ b/docs/html/namespacecub.html @@ -0,0 +1,547 @@ + + + + + + + +CUB: cub Namespace Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ +
+
+ +
+
cub Namespace Reference
+
+
+ +

CUB namespace. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

struct  ArrayTraits
 Array traits. More...
 
struct  BaseTraits
 Basic type traits. More...
 
class  BlockDiscontinuity
 BlockDiscontinuity provides operations for flagging discontinuities within a list of data items partitioned across a CUDA threadblock.

+
+discont_logo.png +
+.
+ More...
 
class  BlockExchange
 BlockExchange provides operations for reorganizing the partitioning of ordered data across a CUDA threadblock.

+
+transpose_logo.png +
+.
+ More...
 
class  BlockLoad
 BlockLoad provides data movement operations for reading block-arranged data from global memory.

+
+block_load_logo.png +
+.
+ More...
 
class  BlockRadixSort
 BlockRadixSort provides variants of parallel radix sorting across a CUDA threadblock.

+
+sorting_logo.png +
+.
+ More...
 
class  BlockReduce
 BlockReduce provides variants of parallel reduction across a CUDA threadblock.

+
+reduce_logo.png +
+.
+ More...
 
class  BlockScan
 BlockScan provides variants of parallel prefix scan (and prefix sum) across a CUDA threadblock.

+
+scan_logo.png +
+.
+ More...
 
class  BlockStore
 BlockStore provides data movement operations for writing blocked-arranged data to global memory.

+
+block_store_logo.png +
+.
+ More...
 
struct  EnableIf
 Simple enable-if (similar to Boost) More...
 
struct  Equality
 Default equality functor. More...
 
struct  Equals
 Type equality test. More...
 
struct  If
 Type selection (IF ? ThenType : ElseType) More...
 
struct  IsVolatile
 Volatile modifier test. More...
 
struct  Log2
 Statically determine log2(N), rounded up. More...
 
struct  Max
 Default max functor. More...
 
struct  NullType
 A simple "NULL" marker type. More...
 
struct  NumericTraits
 Numeric type traits. More...
 
struct  RemoveQualifiers
 Removes const and volatile qualifiers from type Tp. More...
 
struct  Sum
 Default sum functor. More...
 
struct  Traits
 Type traits. More...
 
class  WarpScan
 WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+.
+ More...
 
+ + + + + + + + + + + + + + + + + + + +

+Enumerations

enum  BlockLoadPolicy { BLOCK_LOAD_DIRECT, +BLOCK_LOAD_VECTORIZE, +BLOCK_LOAD_TRANSPOSE + }
 Tuning policy for cub::BlockLoad. More...
 
enum  BlockScanPolicy { BLOCK_SCAN_RAKING, +BLOCK_SCAN_WARPSCANS + }
 Tuning policy for cub::BlockScan. More...
 
enum  BlockStorePolicy { BLOCK_STORE_DIRECT, +BLOCK_STORE_VECTORIZE, +BLOCK_STORE_TRANSPOSE + }
 Tuning policy for cub::BlockStore. More...
 
enum  Category { NOT_A_NUMBER, +SIGNED_INTEGER, +UNSIGNED_INTEGER, +FLOATING_POINT + }
 Basic type traits categories.
 
enum  PtxLoadModifier {
+  PTX_LOAD_NONE, +PTX_LOAD_CA, +PTX_LOAD_CG, +PTX_LOAD_CS, +
+  PTX_LOAD_CV, +PTX_LOAD_LDG, +PTX_LOAD_VS +
+ }
 Enumeration of PTX cache-modifiers for memory load operations. More...
 
enum  PtxStoreModifier {
+  PTX_STORE_NONE, +PTX_STORE_WB, +PTX_STORE_CG, +PTX_STORE_CS, +
+  PTX_STORE_WT, +PTX_STORE_VS +
+ }
 Enumeration of PTX cache-modifiers for memory store operations. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

__host__ __device__
+__forceinline__ cudaError_t 
Debug (cudaError_t error, const char *message, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, message is printed to stderr along with the supplied source context. More...
 
__host__ __device__
+__forceinline__ cudaError_t 
Debug (cudaError_t error, const char *filename, int line)
 If CUB_STDERR is defined and error is not cudaSuccess, the corresponding error message is printed to stderr along with the supplied source context. More...
 
Direct threadblock loads (blocked arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly, guarded by range. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier, guarded by range, with assignment for out-of-bound elements. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirect (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly, guarded by range, with assignment for out-of-bound elements. More...
 
Direct threadblock loads (striped arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped directly tile using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly, guarded by range. More...
 
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped directly tile using the specified cache modifier, guarded by range, with assignment for out-of-bound elements. More...
 
template<typename T , int ITEMS_PER_THREAD, typename InputIterator , typename SizeT >
__device__ __forceinline__ void BlockLoadDirectStriped (InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Load striped tile directly, guarded by range, with assignment for out-of-bound elements. More...
 
Threadblock vectorized loads (blocked arrangement)
template<PtxLoadModifier MODIFIER, typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void BlockLoadVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void BlockLoadVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Load a tile of items across a threadblock directly. More...
 
Direct threadblock stores (blocked arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void BlockStoreDirect (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void BlockStoreDirect (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly. More...
 
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void BlockStoreDirect (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier, guarded by range. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void BlockStoreDirect (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly, guarded by range. More...
 
Direct threadblock stores (striped arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void BlockStoreDirectStriped (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator >
__device__ __forceinline__ void BlockStoreDirectStriped (OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly. More...
 
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void BlockStoreDirectStriped (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 
template<typename T , int ITEMS_PER_THREAD, typename OutputIterator , typename SizeT >
__device__ __forceinline__ void BlockStoreDirectStriped (OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)
 Store striped tile directly, guarded by range. More...
 
Threadblock vectorized stores (blocked arrangement)
template<PtxStoreModifier MODIFIER, typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void BlockStoreVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly using the specified cache modifier. More...
 
template<typename T , int ITEMS_PER_THREAD>
__device__ __forceinline__ void BlockStoreVectorized (T *block_ptr, T(&items)[ITEMS_PER_THREAD])
 Store a tile of items across a threadblock directly. More...
 
Thread utilities for memory I/O using PTX cache modifiers
template<PtxLoadModifier MODIFIER, typename InputIterator >
__device__ __forceinline__
+std::iterator_traits
+< InputIterator >::value_type 
ThreadLoad (InputIterator itr)
 Thread utility for reading memory using cub::PtxLoadModifier cache modifiers. More...
 
template<PtxStoreModifier MODIFIER, typename OutputIterator , typename T >
__device__ __forceinline__ void ThreadStore (OutputIterator itr, const T &val)
 Thread utility for writing memory using cub::PtxStoreModifier cache modifiers. More...
 
+

Detailed Description

+

CUB namespace.

+

Enumeration Type Documentation

+ +
+
+ + + + +
enum cub::BlockScanPolicy
+
+ +

Tuning policy for cub::BlockScan.

+ + + +
Enumerator
BLOCK_SCAN_RAKING  +
Overview
An efficient "raking reduce-then-scan" prefix scan algorithm. Scan execution is comprised of five phases:
    +
  1. Upsweep sequential reduction in registers (if threads contribute more than one input each). Each thread then places the partial reduction of its item(s) into shared memory.
  2. +
  3. Upsweep sequential reduction in shared memory. Threads within a single warp rake across segments of shared partial reductions.
  4. +
  5. A warp-synchronous Kogge-Stone style exclusive scan within the raking warp.
  6. +
  7. Downsweep sequential exclusive scan in shared memory. Threads within a single warp rake across segments of shared partial reductions, seeded with the warp-scan output.
  8. +
  9. Downsweep sequential scan in registers (if threads contribute more than one input), seeded with the raking scan output.
  10. +
+
+
+block_scan_raking.png +
+
BLOCK_SCAN_RAKING data flow for a hypothetical 16-thread threadblock and 4-thread raking warp.
+
Performance Considerations
    +
  • Although this variant may suffer longer turnaround latencies when the GPU is under-occupied, it can often provide higher overall throughput across the GPU when suitably occupied.
  • +
+
+
BLOCK_SCAN_WARPSCANS  +
Overview
A quick "tiled warpscans" prefix scan algorithm. Scan execution is comprised of four phases:
    +
  1. Upsweep sequential reduction in registers (if threads contribute more than one input each). Each thread then places the partial reduction of its item(s) into shared memory.
  2. +
  3. Compute a shallow, but inefficient warp-synchronous Kogge-Stone style scan within each warp.
  4. +
  5. A propagation phase where the warp scan outputs in each warp are updated with the aggregate from each preceding warp.
  6. +
  7. Downsweep sequential scan in registers (if threads contribute more than one input), seeded with the raking scan output.
  8. +
+
+
+block_scan_warpscans.png +
+
BLOCK_SCAN_WARPSCANS data flow for a hypothetical 16-thread threadblock and 4-thread raking warp.
+
Performance Considerations
    +
  • Although this variant may suffer lower overall throughput across the GPU because due to a heavy reliance on inefficient warpscans, it can often provide lower turnaround latencies when the GPU is under-occupied.
  • +
+
+
+ +
+
+ +
+
+ + + + +
enum cub::BlockLoadPolicy
+
+ +

Tuning policy for cub::BlockLoad.

+ + + + +
Enumerator
BLOCK_LOAD_DIRECT  +
Overview
+

A blocked arrangement of data is read directly from memory. The threadblock reads items in a parallel "raking" fashion: threadi reads the ith segment of consecutive elements.

+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) decreases as the access stride between threads increases (i.e., the number items per thread).
  • +
+
+
BLOCK_LOAD_VECTORIZE  +
Overview
+

A blocked arrangement of data is read directly from memory using CUDA's built-in vectorized loads as a coalescing optimization. The threadblock reads items in a parallel "raking" fashion: threadi uses vector loads to read the ith segment of consecutive elements.

+

For example, ld.global.v4.s32 instructions will be generated when T = int and ITEMS_PER_THREAD > 4.

+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) remains high until the the access stride between threads (i.e., the number items per thread) exceeds the maximum vector load width (typically 4 items or 64B, whichever is lower).
  • +
  • The following conditions will prevent vectorization and loading will fall back to cub::BLOCK_LOAD_DIRECT:
      +
    • ITEMS_PER_THREAD is odd
    • +
    • The InputIterator is not a simple pointer type
    • +
    • The block input offset is not quadword-aligned
    • +
    • The data type T is not a built-in primitive or CUDA vector type (e.g., short, int2, double, float2, etc.)
    • +
    +
  • +
+
+
BLOCK_LOAD_TRANSPOSE  +
Overview
+

A striped arrangement of data is read directly from memory and then is locally transposed into a blocked arrangement. The threadblock reads items in a parallel "strip-mining" fashion: threadi reads items having stride BLOCK_THREADS between them. cub::BlockExchange is then used to locally reorder the items into a blocked arrangement.

+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) remains high regardless of items loaded per thread.
  • +
  • The local reordering incurs slightly longer latencies and throughput than the direct cub::BLOCK_LOAD_DIRECT and cub::BLOCK_LOAD_VECTORIZE alternatives.
  • +
+
+
+ +
+
+ +
+
+ + + + +
enum cub::BlockStorePolicy
+
+ +

Tuning policy for cub::BlockStore.

+ + + + +
Enumerator
BLOCK_STORE_DIRECT  +
Overview
+

A blocked arrangement of data is written directly to memory. The threadblock writes items in a parallel "raking" fashion: threadi writes the ith segment of consecutive elements.

+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) decreases as the access stride between threads increases (i.e., the number items per thread).
  • +
+
+
BLOCK_STORE_VECTORIZE  +
Overview
+

A blocked arrangement of data is written directly to memory using CUDA's built-in vectorized stores as a coalescing optimization. The threadblock writes items in a parallel "raking" fashion: threadi uses vector stores to write the ith segment of consecutive elements.

+

For example, st.global.v4.s32 instructions will be generated when T = int and ITEMS_PER_THREAD > 4.

+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) remains high until the the access stride between threads (i.e., the number items per thread) exceeds the maximum vector load width (typically 4 items or 64B, whichever is lower).
  • +
  • The following conditions will prevent vectorization and loading will fall back to cub::BLOCK_STORE_DIRECT:
      +
    • ITEMS_PER_THREAD is odd
    • +
    • The OutputIterator is not a simple pointer type
    • +
    • The block output offset is not quadword-aligned
    • +
    • The data type T is not a built-in primitive or CUDA vector type (e.g., short, int2, double, float2, etc.)
    • +
    +
  • +
+
+
BLOCK_STORE_TRANSPOSE  +
Overview
A blocked arrangement is locally transposed into a striped arrangement which is then written to memory. More specifically, cub::BlockExchange used to locally reorder the items into a striped arrangement, after which the threadblock writes items in a parallel "strip-mining" fashion: consecutive items owned by threadi are written to memory with stride BLOCK_THREADS between them.
+
Performance Considerations
    +
  • The utilization of memory transactions (coalescing) remains high regardless of items written per thread.
  • +
  • The local reordering incurs slightly longer latencies and throughput than the direct cub::BLOCK_STORE_DIRECT and cub::BLOCK_STORE_VECTORIZE alternatives.
  • +
+
+
+ +
+
+
+ + + + + diff --git a/docs/html/nav_f.png b/docs/html/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/docs/html/nav_g.png b/docs/html/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +CUB: operators.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
operators.cuh File Reference
+
+
+
#include "type_utils.cuh"
+#include "ns_wrapper.cuh"
+
+ + + + + + + + + + +

+Classes

struct  cub::Equality< T >
 Default equality functor. More...
 
struct  cub::Max< T >
 Default max functor. More...
 
struct  cub::Sum< T >
 Default sum functor. More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

Simple binary operator functor types

+
+ + + + + diff --git a/cub/docs/images/raking.png b/docs/html/raking.png similarity index 100% rename from cub/docs/images/raking.png rename to docs/html/raking.png diff --git a/cub/docs/images/reduce_logo.png b/docs/html/reduce_logo.png similarity index 100% rename from cub/docs/images/reduce_logo.png rename to docs/html/reduce_logo.png diff --git a/cub/docs/images/scan_logo.png b/docs/html/scan_logo.png similarity index 100% rename from cub/docs/images/scan_logo.png rename to docs/html/scan_logo.png diff --git a/docs/html/search/all_61.html b/docs/html/search/all_61.html new file mode 100644 index 0000000000..f85089b559 --- /dev/null +++ b/docs/html/search/all_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_61.js b/docs/html/search/all_61.js new file mode 100644 index 0000000000..bb41a712e7 --- /dev/null +++ b/docs/html/search/all_61.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['arraytraits',['ArrayTraits',['../structcub_1_1_array_traits.html',1,'cub']]] +]; diff --git a/docs/html/search/all_62.html b/docs/html/search/all_62.html new file mode 100644 index 0000000000..f25fa2c88c --- /dev/null +++ b/docs/html/search/all_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_62.js b/docs/html/search/all_62.js new file mode 100644 index 0000000000..5685f0dcc3 --- /dev/null +++ b/docs/html/search/all_62.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['basetraits',['BaseTraits',['../structcub_1_1_base_traits.html',1,'cub']]], + ['basetraits_3c_20not_5fa_5fnumber_2c_20false_2c_20false_2c_20removequalifiers_3c_20t_20_3e_3a_3atype_20_3e',['BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type >',['../structcub_1_1_base_traits.html',1,'cub']]], + ['basetraits_3c_20not_5fa_5fnumber_2c_20false_2c_20false_2c_20t_20_3e',['BaseTraits< NOT_A_NUMBER, false, false, T >',['../structcub_1_1_base_traits.html',1,'cub']]], + ['block_5fdiscontinuity_2ecuh',['block_discontinuity.cuh',['../block__discontinuity_8cuh.html',1,'']]], + ['block_5fexchange_2ecuh',['block_exchange.cuh',['../block__exchange_8cuh.html',1,'']]], + ['block_5fload_2ecuh',['block_load.cuh',['../block__load_8cuh.html',1,'']]], + ['block_5fload_5fdirect',['BLOCK_LOAD_DIRECT',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290a2d4d8900d7e697e9dac4062e97d3d835',1,'cub']]], + ['block_5fload_5ftranspose',['BLOCK_LOAD_TRANSPOSE',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290acd94f285472e8f7c883a7407f6f4efc4',1,'cub']]], + ['block_5fload_5fvectorize',['BLOCK_LOAD_VECTORIZE',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290a826be9d4df1c44c0e5c00a9c9c136965',1,'cub']]], + ['block_5fradix_5fsort_2ecuh',['block_radix_sort.cuh',['../block__radix__sort_8cuh.html',1,'']]], + ['block_5freduce_2ecuh',['block_reduce.cuh',['../block__reduce_8cuh.html',1,'']]], + ['block_5fscan_2ecuh',['block_scan.cuh',['../block__scan_8cuh.html',1,'']]], + ['block_5fscan_5fraking',['BLOCK_SCAN_RAKING',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1a0fa6cac57b7df2f475a67af053b9371c',1,'cub']]], + ['block_5fscan_5fwarpscans',['BLOCK_SCAN_WARPSCANS',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1a08bbb9b8f17a4b9e568c1333aeda6324',1,'cub']]], + ['block_5fstore_2ecuh',['block_store.cuh',['../block__store_8cuh.html',1,'']]], + ['block_5fstore_5fdirect',['BLOCK_STORE_DIRECT',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189ea9b8dcc7b6b06bcfc24af4f499523b880',1,'cub']]], + ['block_5fstore_5ftranspose',['BLOCK_STORE_TRANSPOSE',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189eab0bbe20613466c3cedfcfea33a97d69c',1,'cub']]], + ['block_5fstore_5fvectorize',['BLOCK_STORE_VECTORIZE',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189ea0ccd625a7f2f3649155cbd5a27adfb41',1,'cub']]], + ['blockdiscontinuity',['BlockDiscontinuity',['../classcub_1_1_block_discontinuity.html',1,'cub']]], + ['blockedtostriped',['BlockedToStriped',['../classcub_1_1_block_exchange.html#a068f68d3f9d5c53920eeae82594d6935',1,'cub::BlockExchange']]], + ['blockexchange',['BlockExchange',['../classcub_1_1_block_exchange.html',1,'cub']]], + ['blockload',['BlockLoad',['../classcub_1_1_block_load.html',1,'cub']]], + ['blockloaddirect',['BlockLoadDirect',['../group___simt_utils.html#ga2ece00cc00c1d3269ee79ddf60d15457',1,'cub::BlockLoadDirect(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga51495fa39938ecf57056d4ca6f0260de',1,'cub::BlockLoadDirect(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga01e0a2d42d5b20aab660815c5cf258a0',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gaac537b6a8c9caaae1e6e77e9717e9541',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gae910789e82acd344d6f5a4cc50beef03',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gac20fbd7aaa120e661575fe6e8028a015',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])']]], + ['blockloaddirectstriped',['BlockLoadDirectStriped',['../group___simt_utils.html#ga10442f4a83e49fb4a414ce6ce9234b79',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga74f3768367f80c79037b3e77c13bf4bc',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga405e4ed36717a6d2c0584578ab94923a',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga7ba15be704f5aa7c7db809a66af43160',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gabf20f04ee43adc4661429a7902f71911',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gaf826ded39a7e107a5f15416d4b147be0',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)']]], + ['blockloadpolicy',['BlockLoadPolicy',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290',1,'cub']]], + ['blockloadvectorized',['BlockLoadVectorized',['../group___simt_utils.html#gaea8200ef976bb588c569e039ea79005c',1,'cub::BlockLoadVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gab1a8ffc7fe70a636a3d09403344cfced',1,'cub::BlockLoadVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])']]], + ['blockradixsort',['BlockRadixSort',['../classcub_1_1_block_radix_sort.html',1,'cub']]], + ['blockreduce',['BlockReduce',['../classcub_1_1_block_reduce.html',1,'cub']]], + ['blockscan',['BlockScan',['../classcub_1_1_block_scan.html',1,'cub']]], + ['blockscanpolicy',['BlockScanPolicy',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1',1,'cub']]], + ['blockstore',['BlockStore',['../classcub_1_1_block_store.html',1,'cub']]], + ['blockstoredirect',['BlockStoreDirect',['../group___simt_utils.html#gaa8f12f02c082f8d689100b8ac88f8f61',1,'cub::BlockStoreDirect(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga2d52e8ce92c8bc044898cc289a7e96b4',1,'cub::BlockStoreDirect(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga8b5f82ad8487072b6cc80b312db1962d',1,'cub::BlockStoreDirect(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga34a623c83894408f4f05ceb788d5ac92',1,'cub::BlockStoreDirect(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]], + ['blockstoredirectstriped',['BlockStoreDirectStriped',['../group___simt_utils.html#gaa18341f23a5d00c1b148e0013a9cc637',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gaed26402e843c84978ce85da24819ebeb',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gadcef89bcc6b3c66e1fa1267c15b08a78',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga75150e5519f86c1054d7a7584e1a4f23',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)']]], + ['blockstorepolicy',['BlockStorePolicy',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189e',1,'cub']]], + ['blockstorevectorized',['BlockStoreVectorized',['../group___simt_utils.html#ga013c3ab8214854f45e8d678958e7dde9',1,'cub::BlockStoreVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga5db0cef20c11ea62aef484c587c4e064',1,'cub::BlockStoreVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])']]], + ['bibliographic_20references',['Bibliographic References',['../citelist.html',1,'']]] +]; diff --git a/docs/html/search/all_63.html b/docs/html/search/all_63.html new file mode 100644 index 0000000000..e7f34db586 --- /dev/null +++ b/docs/html/search/all_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_63.js b/docs/html/search/all_63.js new file mode 100644 index 0000000000..363e157875 --- /dev/null +++ b/docs/html/search/all_63.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['category',['CATEGORY',['../structcub_1_1_base_traits.html#a25ff6477c84dc3bd5f4b5e70cd600f09',1,'cub::BaseTraits::CATEGORY()'],['../namespacecub.html#a4733b6d40e923244502e6f5b200766ef',1,'cub::Category()']]], + ['cub',['cub',['../namespacecub.html',1,'']]], + ['cub_5fhas_5fnested_5ftype',['CUB_HAS_NESTED_TYPE',['../type__utils_8cuh.html#ad785ef798316018015561fda4feec8af',1,'type_utils.cuh']]], + ['cubdebug',['CubDebug',['../debug_8cuh.html#a04236bb0db0efe7a19c9ecba0aedc1e5',1,'debug.cuh']]], + ['cubdebugexit',['CubDebugExit',['../debug_8cuh.html#a2e5de1db78fd84552bda8254efa409a3',1,'debug.cuh']]], + ['cooperative_20simt_20operations',['Cooperative SIMT Operations',['../group___simt_coop.html',1,'']]] +]; diff --git a/docs/html/search/all_64.html b/docs/html/search/all_64.html new file mode 100644 index 0000000000..360601fa72 --- /dev/null +++ b/docs/html/search/all_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_64.js b/docs/html/search/all_64.js new file mode 100644 index 0000000000..163707c8d7 --- /dev/null +++ b/docs/html/search/all_64.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['debug',['Debug',['../group___host_util.html#ga0ac6d9c9d88ac0da0d644c88a3b36aa3',1,'cub::Debug(cudaError_t error, const char *message, const char *filename, int line)'],['../group___host_util.html#ga5a175d2a88f63f7f1ab30e8b4f2cfa95',1,'cub::Debug(cudaError_t error, const char *filename, int line)']]], + ['debug_2ecuh',['debug.cuh',['../debug_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/all_65.html b/docs/html/search/all_65.html new file mode 100644 index 0000000000..c2f4fcd94f --- /dev/null +++ b/docs/html/search/all_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_65.js b/docs/html/search/all_65.js new file mode 100644 index 0000000000..3edb0d15a3 --- /dev/null +++ b/docs/html/search/all_65.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['enableif',['EnableIf',['../structcub_1_1_enable_if.html',1,'cub']]], + ['equality',['Equality',['../structcub_1_1_equality.html',1,'cub']]], + ['equals',['Equals',['../structcub_1_1_equals.html',1,'cub']]], + ['exclusivescan',['ExclusiveScan',['../classcub_1_1_warp_scan.html#ab034c0bd94f866b7044d085f0d354e2d',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#a7ad7b67ebb45eae6d120e55206dace8e',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#af0e55650ffbbb6ad5245c11110fc9343',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_warp_scan.html#ae84a95431640ff2d450c4b0a98dd826e',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#acb0ad5c2aaa0866aa7bcc9a597098daa',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a182cf61f1437c0ac0e3567a9737fcbfe',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#acc948eb8877a6d9956daebf258119b7a',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a64fbe22df260c4731536e1bbcec70cf6',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aa858e1cc0cee3e54fc3fb00bc0ecb3ca',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a2a7bf6b9e06e0ed3a71931f1694359f5',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a86857a9daede055f69299caff5b16259',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a2cdb196b18b1d0eb3f7f85a57ed3ac7e',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a1a0090740c3b47eb018831f36d4fe307',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a929f90d956502a7142fa780647241bf0',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aaea795b16f8a66dbbef62952b5f73643',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#afc79e233524e1e357a4cb77c44a46957',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a05c65595bc59cf1bb0fd04965f3b0988',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#ac8d2690770ba251c6da988936f248da5',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)']]], + ['exclusivesum',['ExclusiveSum',['../classcub_1_1_warp_scan.html#a2695420235a1ace8817a595a6f930d61',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_warp_scan.html#a2a7c0b9abd940adf1b76e1d5931fcfd7',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a8b9720f46d2b9cb920c4eb8a6543fc2c',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a01676b552903e7b5d240bbde7968d55e',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aa4b6abbc17343b897a7b93d581620164',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)'],['../classcub_1_1_block_scan.html#af0fb65e2f9663daaee32390dee4c786b',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a9adb14da21b88da067e0dae60c628183',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a8e661f683b84c496a0f1bcd96d5bb528',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_block_scan.html#a1414392abb5dc2f60386130ad8ad5130',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/all_66.html b/docs/html/search/all_66.html new file mode 100644 index 0000000000..a9ac881c03 --- /dev/null +++ b/docs/html/search/all_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_66.js b/docs/html/search/all_66.js new file mode 100644 index 0000000000..a09c3361bc --- /dev/null +++ b/docs/html/search/all_66.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['flag',['Flag',['../classcub_1_1_block_discontinuity.html#ab6390151f109ac253810504ddc5a7c04',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)'],['../classcub_1_1_block_discontinuity.html#a3bdf3b7ad8ace5249f84e103f25ff3bb',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_discontinuity.html#a7fa4c2dc8bbe5db5da50fedca0613b46',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)'],['../classcub_1_1_block_discontinuity.html#a351ed32eaada93c944fbb29feda5a6cd',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/all_68.html b/docs/html/search/all_68.html new file mode 100644 index 0000000000..dec41d62ef --- /dev/null +++ b/docs/html/search/all_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_68.js b/docs/html/search/all_68.js new file mode 100644 index 0000000000..8fcb135372 --- /dev/null +++ b/docs/html/search/all_68.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['host_20utilities',['Host Utilities',['../group___host_util.html',1,'']]] +]; diff --git a/docs/html/search/all_69.html b/docs/html/search/all_69.html new file mode 100644 index 0000000000..192e4bab2a --- /dev/null +++ b/docs/html/search/all_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_69.js b/docs/html/search/all_69.js new file mode 100644 index 0000000000..08639b4672 --- /dev/null +++ b/docs/html/search/all_69.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['if',['If',['../structcub_1_1_if.html',1,'cub']]], + ['inclusivescan',['InclusiveScan',['../classcub_1_1_warp_scan.html#a9f0397ded5ce89a8750dc8fe10078f3e',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#a4df11b322777066e9237fc2ef3d257e5',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#ae5e4f735a2bda14ad6a94a68a0528bd1',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a981f9bae42f6f9c5fe6950698b97d8d4',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a0b750ea27539a71e46657f3d63fdbce6',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a4b987cb649f4aced568b77bd9ac18db6',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#aae6c7a0cdb8ea21cd7eac0cecacd1ac1',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#ac5220b7189e39eb4ff67430f732b1f96',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a046dfe9d6daa55a0d9c74d6ce2f7aa5b',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)']]], + ['inclusivesum',['InclusiveSum',['../classcub_1_1_warp_scan.html#adec85c76d951c326e592e364aa63c728',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_warp_scan.html#a78bf6035a0bccc58913dc0ec570c487d',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a032ce184b653241719effbd0b5b2dbcd',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a738fa570c0a0e391397c342eaab388cb',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a88a16a5a98fadb09fa216b2d234f0b86',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)'],['../classcub_1_1_block_scan.html#aed86bb94fe1908673dadbbaec0f95362',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a47978bae019da4e99c30519de96534a4',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#af4bfc827149cbcfd741e578cfaeee5c7',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_block_scan.html#ae9562dc6cb1e745c8714668dcef3e5b1',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])']]], + ['isvolatile',['IsVolatile',['../structcub_1_1_is_volatile.html',1,'cub']]] +]; diff --git a/docs/html/search/all_6c.html b/docs/html/search/all_6c.html new file mode 100644 index 0000000000..ae8bc48da3 --- /dev/null +++ b/docs/html/search/all_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_6c.js b/docs/html/search/all_6c.js new file mode 100644 index 0000000000..cbd18f7293 --- /dev/null +++ b/docs/html/search/all_6c.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['load',['Load',['../classcub_1_1_block_load.html#ac671e9f033037fc01384a9296684200c',1,'cub::BlockLoad::Load(SmemStorage &smem_storage, InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_load.html#ae7025d183926de0430146d41b5771032',1,'cub::BlockLoad::Load(SmemStorage &smem_storage, InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]], + ['log2',['Log2',['../structcub_1_1_log2.html',1,'cub']]] +]; diff --git a/docs/html/search/all_6d.html b/docs/html/search/all_6d.html new file mode 100644 index 0000000000..ee90718ff2 --- /dev/null +++ b/docs/html/search/all_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_6d.js b/docs/html/search/all_6d.js new file mode 100644 index 0000000000..3432b9e7a8 --- /dev/null +++ b/docs/html/search/all_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['max',['Max',['../structcub_1_1_max.html',1,'cub']]] +]; diff --git a/docs/html/search/all_6e.html b/docs/html/search/all_6e.html new file mode 100644 index 0000000000..e0fd7653a0 --- /dev/null +++ b/docs/html/search/all_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_6e.js b/docs/html/search/all_6e.js new file mode 100644 index 0000000000..8c05a0bd37 --- /dev/null +++ b/docs/html/search/all_6e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['nulltype',['NullType',['../structcub_1_1_null_type.html',1,'cub']]], + ['numerictraits',['NumericTraits',['../structcub_1_1_numeric_traits.html',1,'cub']]], + ['numerictraits_3c_20removequalifiers_3c_20t_20_3e_3a_3atype_20_3e',['NumericTraits< RemoveQualifiers< T >::Type >',['../structcub_1_1_numeric_traits.html',1,'cub']]] +]; diff --git a/docs/html/search/all_6f.html b/docs/html/search/all_6f.html new file mode 100644 index 0000000000..5e86b030d2 --- /dev/null +++ b/docs/html/search/all_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_6f.js b/docs/html/search/all_6f.js new file mode 100644 index 0000000000..5f733c3055 --- /dev/null +++ b/docs/html/search/all_6f.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['operator_28_29',['operator()',['../structcub_1_1_equality.html#a89f91d9fabb6b8237f97307ce04f1bab',1,'cub::Equality::operator()()'],['../structcub_1_1_sum.html#a05a1ac22d3e5c852dec8c39724297fe3',1,'cub::Sum::operator()()'],['../structcub_1_1_max.html#a880bd2cf50b320c1771eafe31ebf9ea1',1,'cub::Max::operator()()']]], + ['operators_2ecuh',['operators.cuh',['../operators_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/all_70.html b/docs/html/search/all_70.html new file mode 100644 index 0000000000..799c1a277d --- /dev/null +++ b/docs/html/search/all_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_70.js b/docs/html/search/all_70.js new file mode 100644 index 0000000000..dcfc9123ce --- /dev/null +++ b/docs/html/search/all_70.js @@ -0,0 +1,18 @@ +var searchData= +[ + ['ptx_5fload_5fca',['PTX_LOAD_CA',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dad802bce71c7380a911ab0cee5b366fd3',1,'cub']]], + ['ptx_5fload_5fcg',['PTX_LOAD_CG',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da0e18a5a910be460d738772631eafadd0',1,'cub']]], + ['ptx_5fload_5fcs',['PTX_LOAD_CS',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da0b263e2237593103d5e9004e935c66af',1,'cub']]], + ['ptx_5fload_5fcv',['PTX_LOAD_CV',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da05ee1b160fa298ef4b2578a9df1c1350',1,'cub']]], + ['ptx_5fload_5fldg',['PTX_LOAD_LDG',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dae8ca2d6545712389c0578224f214913d',1,'cub']]], + ['ptx_5fload_5fnone',['PTX_LOAD_NONE',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da017db24b99abd332be14151d35fa3cf5',1,'cub']]], + ['ptx_5fload_5fvs',['PTX_LOAD_VS',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dae4cbe986a2413b418ec83e8bb153b990',1,'cub']]], + ['ptx_5fstore_5fcg',['PTX_STORE_CG',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a95a2bc222f2adce9dd2d0251f53e1d91',1,'cub']]], + ['ptx_5fstore_5fcs',['PTX_STORE_CS',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2ac08bd33e1c4694ccdb899dd9bdef9c96',1,'cub']]], + ['ptx_5fstore_5fnone',['PTX_STORE_NONE',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a5437dabe5d300b7188dbb42132363c05',1,'cub']]], + ['ptx_5fstore_5fvs',['PTX_STORE_VS',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2adee47f52a9358d88446393c5affd11aa',1,'cub']]], + ['ptx_5fstore_5fwb',['PTX_STORE_WB',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a2d57d44c3dbebbae63abcc3ccb80a412',1,'cub']]], + ['ptx_5fstore_5fwt',['PTX_STORE_WT',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a8d07fc5099d72afdc46b817d566d3df8',1,'cub']]], + ['ptxloadmodifier',['PtxLoadModifier',['../group___simt_utils.html#ga023420f30fec7d4b187fc98f4fd2a55d',1,'cub']]], + ['ptxstoremodifier',['PtxStoreModifier',['../group___simt_utils.html#gae9c7d6a6af7104f528509182ac9c9da2',1,'cub']]] +]; diff --git a/docs/html/search/all_72.html b/docs/html/search/all_72.html new file mode 100644 index 0000000000..347b9f6660 --- /dev/null +++ b/docs/html/search/all_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_72.js b/docs/html/search/all_72.js new file mode 100644 index 0000000000..e3c6279e2b --- /dev/null +++ b/docs/html/search/all_72.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['reduce',['Reduce',['../classcub_1_1_block_reduce.html#aee16d11eea520e487f387b7d9f2755d2',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op)'],['../classcub_1_1_block_reduce.html#acc9a5597731b4985fac1e8a90153d979',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD], ReductionOp reduction_op)'],['../classcub_1_1_block_reduce.html#aeddda91425d07c74b819d34ac5b7a0a6',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op, const unsigned int &valid_threads)']]], + ['removequalifiers',['RemoveQualifiers',['../structcub_1_1_remove_qualifiers.html',1,'cub']]] +]; diff --git a/docs/html/search/all_73.html b/docs/html/search/all_73.html new file mode 100644 index 0000000000..9abac91a94 --- /dev/null +++ b/docs/html/search/all_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_73.js b/docs/html/search/all_73.js new file mode 100644 index 0000000000..a6f19fd8bf --- /dev/null +++ b/docs/html/search/all_73.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['scattertoblocked',['ScatterToBlocked',['../classcub_1_1_block_exchange.html#a7a429434bbdc3e949a8291461a74bff9',1,'cub::BlockExchange']]], + ['scattertostriped',['ScatterToStriped',['../classcub_1_1_block_exchange.html#a8b8997367d0d42ee7eb600b981f7b72d',1,'cub::BlockExchange']]], + ['simt_20primitives',['SIMT Primitives',['../group___simt.html',1,'']]], + ['simt_20utilities',['SIMT Utilities',['../group___simt_utils.html',1,'']]], + ['smemstorage',['SmemStorage',['../classcub_1_1_warp_scan.html#a2bfa864e963cb4965139ac1b6c66d1b7',1,'cub::WarpScan::SmemStorage()'],['../classcub_1_1_block_reduce.html#aea61e2e067e0e2d3fba2b0c8e0f73d8d',1,'cub::BlockReduce::SmemStorage()'],['../classcub_1_1_block_scan.html#abda6008896e2e17b50c7deb0ab320e64',1,'cub::BlockScan::SmemStorage()'],['../classcub_1_1_block_radix_sort.html#a495e63ab526ce35e6dfce9fb5206746c',1,'cub::BlockRadixSort::SmemStorage()'],['../classcub_1_1_block_load.html#a09296fd690f1452df9cae24a037e906a',1,'cub::BlockLoad::SmemStorage()'],['../classcub_1_1_block_store.html#aa80c1691bc7aa80bc38c2797b3a99c24',1,'cub::BlockStore::SmemStorage()'],['../classcub_1_1_block_exchange.html#ad91573946e4abe5ae5e34277ded1c215',1,'cub::BlockExchange::SmemStorage()'],['../classcub_1_1_block_discontinuity.html#a855c92f9c3869909913860fa11e755a4',1,'cub::BlockDiscontinuity::SmemStorage()']]], + ['sortblocked',['SortBlocked',['../classcub_1_1_block_radix_sort.html#abdbfda59c129946222ab10d2e2e6f6f5',1,'cub::BlockRadixSort::SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#a7e304558942536fc1636849f8d93d896',1,'cub::BlockRadixSort::SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['sortblockedtostriped',['SortBlockedToStriped',['../classcub_1_1_block_radix_sort.html#ac7fe497d674f5da3062a3d34f010f438',1,'cub::BlockRadixSort::SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#ab1a7c9c9e536f13741b4c4f6c369ce80',1,'cub::BlockRadixSort::SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['sortstriped',['SortStriped',['../classcub_1_1_block_radix_sort.html#a81e081320239182670da329c2b036166',1,'cub::BlockRadixSort::SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#a0c730daecd6cc6f69135ae36d11d5c53',1,'cub::BlockRadixSort::SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['store',['Store',['../classcub_1_1_block_store.html#a1fc63a32e80b1275145a469e719f8530',1,'cub::BlockStore::Store(SmemStorage &smem_storage, OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_store.html#a3c1f7f37767338869f44e410a90f2255',1,'cub::BlockStore::Store(SmemStorage &smem_storage, OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]], + ['stripedtoblocked',['StripedToBlocked',['../classcub_1_1_block_exchange.html#ad8000bf73c3ce935018f32451985ae37',1,'cub::BlockExchange']]], + ['sum',['Sum',['../classcub_1_1_block_reduce.html#a136060887c434257984b8bf3f5c62323',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T input)'],['../classcub_1_1_block_reduce.html#abe33a10ae2e316943e95d23f1d4d702a',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_reduce.html#aad43736f8ea38a2c9052059b1d80c7fc',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T input, const unsigned int &valid_threads)']]], + ['sum',['Sum',['../structcub_1_1_sum.html',1,'cub']]] +]; diff --git a/docs/html/search/all_74.html b/docs/html/search/all_74.html new file mode 100644 index 0000000000..c646aeffcd --- /dev/null +++ b/docs/html/search/all_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_74.js b/docs/html/search/all_74.js new file mode 100644 index 0000000000..df33641f84 --- /dev/null +++ b/docs/html/search/all_74.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['thread_5fload_2ecuh',['thread_load.cuh',['../thread__load_8cuh.html',1,'']]], + ['thread_5fstore_2ecuh',['thread_store.cuh',['../thread__store_8cuh.html',1,'']]], + ['threadload',['ThreadLoad',['../group___simt_utils.html#ga1e390b9fee4c8012a021d49d9b76b1e8',1,'cub']]], + ['threadstore',['ThreadStore',['../group___simt_utils.html#gad117ecb99b9230a032971b0ac08ca6dc',1,'cub']]], + ['traits',['Traits',['../structcub_1_1_traits.html',1,'cub']]], + ['type',['Type',['../structcub_1_1_if.html#af689e9527f56372e66413b65581ded8e',1,'cub::If::Type()'],['../structcub_1_1_remove_qualifiers.html#a9143e196ef5e6a0176b953f677e94671',1,'cub::RemoveQualifiers::Type()'],['../structcub_1_1_enable_if.html#aafd9405b5887d2a6d3553eee0202798a',1,'cub::EnableIf::Type()']]], + ['type_5futils_2ecuh',['type_utils.cuh',['../type__utils_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/all_76.html b/docs/html/search/all_76.html new file mode 100644 index 0000000000..50b86daa03 --- /dev/null +++ b/docs/html/search/all_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_76.js b/docs/html/search/all_76.js new file mode 100644 index 0000000000..58c39304d9 --- /dev/null +++ b/docs/html/search/all_76.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value',['VALUE',['../structcub_1_1_log2.html#ad1923657cb57427a8621f53022590cd2',1,'cub::Log2']]] +]; diff --git a/docs/html/search/all_77.html b/docs/html/search/all_77.html new file mode 100644 index 0000000000..55d7142924 --- /dev/null +++ b/docs/html/search/all_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_77.js b/docs/html/search/all_77.js new file mode 100644 index 0000000000..d61ee34071 --- /dev/null +++ b/docs/html/search/all_77.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['warp_5fscan_2ecuh',['warp_scan.cuh',['../warp__scan_8cuh.html',1,'']]], + ['warpscan',['WarpScan',['../classcub_1_1_warp_scan.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_61.html b/docs/html/search/classes_61.html new file mode 100644 index 0000000000..a4c07d590c --- /dev/null +++ b/docs/html/search/classes_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_61.js b/docs/html/search/classes_61.js new file mode 100644 index 0000000000..bb41a712e7 --- /dev/null +++ b/docs/html/search/classes_61.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['arraytraits',['ArrayTraits',['../structcub_1_1_array_traits.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_62.html b/docs/html/search/classes_62.html new file mode 100644 index 0000000000..04a59d2efe --- /dev/null +++ b/docs/html/search/classes_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_62.js b/docs/html/search/classes_62.js new file mode 100644 index 0000000000..a70ac445b6 --- /dev/null +++ b/docs/html/search/classes_62.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['basetraits',['BaseTraits',['../structcub_1_1_base_traits.html',1,'cub']]], + ['basetraits_3c_20not_5fa_5fnumber_2c_20false_2c_20false_2c_20removequalifiers_3c_20t_20_3e_3a_3atype_20_3e',['BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type >',['../structcub_1_1_base_traits.html',1,'cub']]], + ['basetraits_3c_20not_5fa_5fnumber_2c_20false_2c_20false_2c_20t_20_3e',['BaseTraits< NOT_A_NUMBER, false, false, T >',['../structcub_1_1_base_traits.html',1,'cub']]], + ['blockdiscontinuity',['BlockDiscontinuity',['../classcub_1_1_block_discontinuity.html',1,'cub']]], + ['blockexchange',['BlockExchange',['../classcub_1_1_block_exchange.html',1,'cub']]], + ['blockload',['BlockLoad',['../classcub_1_1_block_load.html',1,'cub']]], + ['blockradixsort',['BlockRadixSort',['../classcub_1_1_block_radix_sort.html',1,'cub']]], + ['blockreduce',['BlockReduce',['../classcub_1_1_block_reduce.html',1,'cub']]], + ['blockscan',['BlockScan',['../classcub_1_1_block_scan.html',1,'cub']]], + ['blockstore',['BlockStore',['../classcub_1_1_block_store.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_65.html b/docs/html/search/classes_65.html new file mode 100644 index 0000000000..4f441f9def --- /dev/null +++ b/docs/html/search/classes_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_65.js b/docs/html/search/classes_65.js new file mode 100644 index 0000000000..4a2fca4174 --- /dev/null +++ b/docs/html/search/classes_65.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['enableif',['EnableIf',['../structcub_1_1_enable_if.html',1,'cub']]], + ['equality',['Equality',['../structcub_1_1_equality.html',1,'cub']]], + ['equals',['Equals',['../structcub_1_1_equals.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_69.html b/docs/html/search/classes_69.html new file mode 100644 index 0000000000..7a0d013683 --- /dev/null +++ b/docs/html/search/classes_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_69.js b/docs/html/search/classes_69.js new file mode 100644 index 0000000000..8b9fcc1a49 --- /dev/null +++ b/docs/html/search/classes_69.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['if',['If',['../structcub_1_1_if.html',1,'cub']]], + ['isvolatile',['IsVolatile',['../structcub_1_1_is_volatile.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_6c.html b/docs/html/search/classes_6c.html new file mode 100644 index 0000000000..a16bb58f62 --- /dev/null +++ b/docs/html/search/classes_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_6c.js b/docs/html/search/classes_6c.js new file mode 100644 index 0000000000..b55816e39b --- /dev/null +++ b/docs/html/search/classes_6c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['log2',['Log2',['../structcub_1_1_log2.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_6d.html b/docs/html/search/classes_6d.html new file mode 100644 index 0000000000..12b1c839ae --- /dev/null +++ b/docs/html/search/classes_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_6d.js b/docs/html/search/classes_6d.js new file mode 100644 index 0000000000..3432b9e7a8 --- /dev/null +++ b/docs/html/search/classes_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['max',['Max',['../structcub_1_1_max.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_6e.html b/docs/html/search/classes_6e.html new file mode 100644 index 0000000000..a183c15e22 --- /dev/null +++ b/docs/html/search/classes_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_6e.js b/docs/html/search/classes_6e.js new file mode 100644 index 0000000000..8c05a0bd37 --- /dev/null +++ b/docs/html/search/classes_6e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['nulltype',['NullType',['../structcub_1_1_null_type.html',1,'cub']]], + ['numerictraits',['NumericTraits',['../structcub_1_1_numeric_traits.html',1,'cub']]], + ['numerictraits_3c_20removequalifiers_3c_20t_20_3e_3a_3atype_20_3e',['NumericTraits< RemoveQualifiers< T >::Type >',['../structcub_1_1_numeric_traits.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_72.html b/docs/html/search/classes_72.html new file mode 100644 index 0000000000..03a77208fb --- /dev/null +++ b/docs/html/search/classes_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_72.js b/docs/html/search/classes_72.js new file mode 100644 index 0000000000..190feb2666 --- /dev/null +++ b/docs/html/search/classes_72.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['removequalifiers',['RemoveQualifiers',['../structcub_1_1_remove_qualifiers.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_73.html b/docs/html/search/classes_73.html new file mode 100644 index 0000000000..f447c456fe --- /dev/null +++ b/docs/html/search/classes_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_73.js b/docs/html/search/classes_73.js new file mode 100644 index 0000000000..47174d1acd --- /dev/null +++ b/docs/html/search/classes_73.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['sum',['Sum',['../structcub_1_1_sum.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_74.html b/docs/html/search/classes_74.html new file mode 100644 index 0000000000..4b0fdaa160 --- /dev/null +++ b/docs/html/search/classes_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_74.js b/docs/html/search/classes_74.js new file mode 100644 index 0000000000..cb6fc21918 --- /dev/null +++ b/docs/html/search/classes_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['traits',['Traits',['../structcub_1_1_traits.html',1,'cub']]] +]; diff --git a/docs/html/search/classes_77.html b/docs/html/search/classes_77.html new file mode 100644 index 0000000000..dd06de9930 --- /dev/null +++ b/docs/html/search/classes_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_77.js b/docs/html/search/classes_77.js new file mode 100644 index 0000000000..3e7deeeae5 --- /dev/null +++ b/docs/html/search/classes_77.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['warpscan',['WarpScan',['../classcub_1_1_warp_scan.html',1,'cub']]] +]; diff --git a/docs/html/search/close.png b/docs/html/search/close.png new file mode 100644 index 0000000000000000000000000000000000000000..9342d3dfeea7b7c4ee610987e717804b5a42ceb9 GIT binary patch literal 273 zcmV+s0q*{ZP)4(RlMby96)VwnbG{ zbe&}^BDn7x>$<{ck4zAK-=nT;=hHG)kmplIF${xqm8db3oX6wT3bvp`TE@m0cg;b) zBuSL}5?N7O(iZLdAlz@)b)Rd~DnSsSX&P5qC`XwuFwcAYLC+d2>+1(8on;wpt8QIC X2MT$R4iQDd00000NkvXXu0mjfia~GN literal 0 HcmV?d00001 diff --git a/docs/html/search/defines_63.html b/docs/html/search/defines_63.html new file mode 100644 index 0000000000..67967fbce3 --- /dev/null +++ b/docs/html/search/defines_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/defines_63.js b/docs/html/search/defines_63.js new file mode 100644 index 0000000000..b9a79c5ce3 --- /dev/null +++ b/docs/html/search/defines_63.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['cub_5fhas_5fnested_5ftype',['CUB_HAS_NESTED_TYPE',['../type__utils_8cuh.html#ad785ef798316018015561fda4feec8af',1,'type_utils.cuh']]], + ['cubdebug',['CubDebug',['../debug_8cuh.html#a04236bb0db0efe7a19c9ecba0aedc1e5',1,'debug.cuh']]], + ['cubdebugexit',['CubDebugExit',['../debug_8cuh.html#a2e5de1db78fd84552bda8254efa409a3',1,'debug.cuh']]] +]; diff --git a/docs/html/search/enums_62.html b/docs/html/search/enums_62.html new file mode 100644 index 0000000000..e8fef345b1 --- /dev/null +++ b/docs/html/search/enums_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enums_62.js b/docs/html/search/enums_62.js new file mode 100644 index 0000000000..5025d0a762 --- /dev/null +++ b/docs/html/search/enums_62.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['blockloadpolicy',['BlockLoadPolicy',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290',1,'cub']]], + ['blockscanpolicy',['BlockScanPolicy',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1',1,'cub']]], + ['blockstorepolicy',['BlockStorePolicy',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189e',1,'cub']]] +]; diff --git a/docs/html/search/enums_63.html b/docs/html/search/enums_63.html new file mode 100644 index 0000000000..e8a1e6c81b --- /dev/null +++ b/docs/html/search/enums_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enums_63.js b/docs/html/search/enums_63.js new file mode 100644 index 0000000000..94d5e5b1d7 --- /dev/null +++ b/docs/html/search/enums_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['category',['Category',['../namespacecub.html#a4733b6d40e923244502e6f5b200766ef',1,'cub']]] +]; diff --git a/docs/html/search/enums_70.html b/docs/html/search/enums_70.html new file mode 100644 index 0000000000..d737ab2180 --- /dev/null +++ b/docs/html/search/enums_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enums_70.js b/docs/html/search/enums_70.js new file mode 100644 index 0000000000..186c349234 --- /dev/null +++ b/docs/html/search/enums_70.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['ptxloadmodifier',['PtxLoadModifier',['../group___simt_utils.html#ga023420f30fec7d4b187fc98f4fd2a55d',1,'cub']]], + ['ptxstoremodifier',['PtxStoreModifier',['../group___simt_utils.html#gae9c7d6a6af7104f528509182ac9c9da2',1,'cub']]] +]; diff --git a/docs/html/search/enumvalues_62.html b/docs/html/search/enumvalues_62.html new file mode 100644 index 0000000000..ecbeb60860 --- /dev/null +++ b/docs/html/search/enumvalues_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enumvalues_62.js b/docs/html/search/enumvalues_62.js new file mode 100644 index 0000000000..ec2d47019f --- /dev/null +++ b/docs/html/search/enumvalues_62.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['block_5fload_5fdirect',['BLOCK_LOAD_DIRECT',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290a2d4d8900d7e697e9dac4062e97d3d835',1,'cub']]], + ['block_5fload_5ftranspose',['BLOCK_LOAD_TRANSPOSE',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290acd94f285472e8f7c883a7407f6f4efc4',1,'cub']]], + ['block_5fload_5fvectorize',['BLOCK_LOAD_VECTORIZE',['../namespacecub.html#a70f1d3c7536d858d49b896e937d25290a826be9d4df1c44c0e5c00a9c9c136965',1,'cub']]], + ['block_5fscan_5fraking',['BLOCK_SCAN_RAKING',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1a0fa6cac57b7df2f475a67af053b9371c',1,'cub']]], + ['block_5fscan_5fwarpscans',['BLOCK_SCAN_WARPSCANS',['../namespacecub.html#aa7484021273cbfd89229a6b5c205b9f1a08bbb9b8f17a4b9e568c1333aeda6324',1,'cub']]], + ['block_5fstore_5fdirect',['BLOCK_STORE_DIRECT',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189ea9b8dcc7b6b06bcfc24af4f499523b880',1,'cub']]], + ['block_5fstore_5ftranspose',['BLOCK_STORE_TRANSPOSE',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189eab0bbe20613466c3cedfcfea33a97d69c',1,'cub']]], + ['block_5fstore_5fvectorize',['BLOCK_STORE_VECTORIZE',['../namespacecub.html#aaaa9ee8c8a57c6607909c110affd189ea0ccd625a7f2f3649155cbd5a27adfb41',1,'cub']]] +]; diff --git a/docs/html/search/enumvalues_70.html b/docs/html/search/enumvalues_70.html new file mode 100644 index 0000000000..0b609cb11b --- /dev/null +++ b/docs/html/search/enumvalues_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enumvalues_70.js b/docs/html/search/enumvalues_70.js new file mode 100644 index 0000000000..118397b377 --- /dev/null +++ b/docs/html/search/enumvalues_70.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['ptx_5fload_5fca',['PTX_LOAD_CA',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dad802bce71c7380a911ab0cee5b366fd3',1,'cub']]], + ['ptx_5fload_5fcg',['PTX_LOAD_CG',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da0e18a5a910be460d738772631eafadd0',1,'cub']]], + ['ptx_5fload_5fcs',['PTX_LOAD_CS',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da0b263e2237593103d5e9004e935c66af',1,'cub']]], + ['ptx_5fload_5fcv',['PTX_LOAD_CV',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da05ee1b160fa298ef4b2578a9df1c1350',1,'cub']]], + ['ptx_5fload_5fldg',['PTX_LOAD_LDG',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dae8ca2d6545712389c0578224f214913d',1,'cub']]], + ['ptx_5fload_5fnone',['PTX_LOAD_NONE',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55da017db24b99abd332be14151d35fa3cf5',1,'cub']]], + ['ptx_5fload_5fvs',['PTX_LOAD_VS',['../group___simt_utils.html#gga023420f30fec7d4b187fc98f4fd2a55dae4cbe986a2413b418ec83e8bb153b990',1,'cub']]], + ['ptx_5fstore_5fcg',['PTX_STORE_CG',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a95a2bc222f2adce9dd2d0251f53e1d91',1,'cub']]], + ['ptx_5fstore_5fcs',['PTX_STORE_CS',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2ac08bd33e1c4694ccdb899dd9bdef9c96',1,'cub']]], + ['ptx_5fstore_5fnone',['PTX_STORE_NONE',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a5437dabe5d300b7188dbb42132363c05',1,'cub']]], + ['ptx_5fstore_5fvs',['PTX_STORE_VS',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2adee47f52a9358d88446393c5affd11aa',1,'cub']]], + ['ptx_5fstore_5fwb',['PTX_STORE_WB',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a2d57d44c3dbebbae63abcc3ccb80a412',1,'cub']]], + ['ptx_5fstore_5fwt',['PTX_STORE_WT',['../group___simt_utils.html#ggae9c7d6a6af7104f528509182ac9c9da2a8d07fc5099d72afdc46b817d566d3df8',1,'cub']]] +]; diff --git a/docs/html/search/files_62.html b/docs/html/search/files_62.html new file mode 100644 index 0000000000..86dfe39e68 --- /dev/null +++ b/docs/html/search/files_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_62.js b/docs/html/search/files_62.js new file mode 100644 index 0000000000..d96228005f --- /dev/null +++ b/docs/html/search/files_62.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['block_5fdiscontinuity_2ecuh',['block_discontinuity.cuh',['../block__discontinuity_8cuh.html',1,'']]], + ['block_5fexchange_2ecuh',['block_exchange.cuh',['../block__exchange_8cuh.html',1,'']]], + ['block_5fload_2ecuh',['block_load.cuh',['../block__load_8cuh.html',1,'']]], + ['block_5fradix_5fsort_2ecuh',['block_radix_sort.cuh',['../block__radix__sort_8cuh.html',1,'']]], + ['block_5freduce_2ecuh',['block_reduce.cuh',['../block__reduce_8cuh.html',1,'']]], + ['block_5fscan_2ecuh',['block_scan.cuh',['../block__scan_8cuh.html',1,'']]], + ['block_5fstore_2ecuh',['block_store.cuh',['../block__store_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/files_64.html b/docs/html/search/files_64.html new file mode 100644 index 0000000000..175a900cc5 --- /dev/null +++ b/docs/html/search/files_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_64.js b/docs/html/search/files_64.js new file mode 100644 index 0000000000..0a441a33f0 --- /dev/null +++ b/docs/html/search/files_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['debug_2ecuh',['debug.cuh',['../debug_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/files_6f.html b/docs/html/search/files_6f.html new file mode 100644 index 0000000000..4f9b7bbdba --- /dev/null +++ b/docs/html/search/files_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_6f.js b/docs/html/search/files_6f.js new file mode 100644 index 0000000000..5192f4553e --- /dev/null +++ b/docs/html/search/files_6f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['operators_2ecuh',['operators.cuh',['../operators_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/files_74.html b/docs/html/search/files_74.html new file mode 100644 index 0000000000..985db86908 --- /dev/null +++ b/docs/html/search/files_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_74.js b/docs/html/search/files_74.js new file mode 100644 index 0000000000..802bcd3b36 --- /dev/null +++ b/docs/html/search/files_74.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['thread_5fload_2ecuh',['thread_load.cuh',['../thread__load_8cuh.html',1,'']]], + ['thread_5fstore_2ecuh',['thread_store.cuh',['../thread__store_8cuh.html',1,'']]], + ['type_5futils_2ecuh',['type_utils.cuh',['../type__utils_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/files_77.html b/docs/html/search/files_77.html new file mode 100644 index 0000000000..63bf92c096 --- /dev/null +++ b/docs/html/search/files_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_77.js b/docs/html/search/files_77.js new file mode 100644 index 0000000000..8be4ab6ca7 --- /dev/null +++ b/docs/html/search/files_77.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['warp_5fscan_2ecuh',['warp_scan.cuh',['../warp__scan_8cuh.html',1,'']]] +]; diff --git a/docs/html/search/functions_62.html b/docs/html/search/functions_62.html new file mode 100644 index 0000000000..5134d2d296 --- /dev/null +++ b/docs/html/search/functions_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_62.js b/docs/html/search/functions_62.js new file mode 100644 index 0000000000..3336b785a3 --- /dev/null +++ b/docs/html/search/functions_62.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['blockedtostriped',['BlockedToStriped',['../classcub_1_1_block_exchange.html#a068f68d3f9d5c53920eeae82594d6935',1,'cub::BlockExchange']]], + ['blockloaddirect',['BlockLoadDirect',['../group___simt_utils.html#ga2ece00cc00c1d3269ee79ddf60d15457',1,'cub::BlockLoadDirect(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga51495fa39938ecf57056d4ca6f0260de',1,'cub::BlockLoadDirect(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga01e0a2d42d5b20aab660815c5cf258a0',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gaac537b6a8c9caaae1e6e77e9717e9541',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gae910789e82acd344d6f5a4cc50beef03',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gac20fbd7aaa120e661575fe6e8028a015',1,'cub::BlockLoadDirect(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD])']]], + ['blockloaddirectstriped',['BlockLoadDirectStriped',['../group___simt_utils.html#ga10442f4a83e49fb4a414ce6ce9234b79',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga74f3768367f80c79037b3e77c13bf4bc',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga405e4ed36717a6d2c0584578ab94923a',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga7ba15be704f5aa7c7db809a66af43160',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gabf20f04ee43adc4661429a7902f71911',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gaf826ded39a7e107a5f15416d4b147be0',1,'cub::BlockLoadDirectStriped(InputIterator block_itr, const SizeT &guarded_items, T oob_default, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)']]], + ['blockloadvectorized',['BlockLoadVectorized',['../group___simt_utils.html#gaea8200ef976bb588c569e039ea79005c',1,'cub::BlockLoadVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#gab1a8ffc7fe70a636a3d09403344cfced',1,'cub::BlockLoadVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])']]], + ['blockstoredirect',['BlockStoreDirect',['../group___simt_utils.html#gaa8f12f02c082f8d689100b8ac88f8f61',1,'cub::BlockStoreDirect(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga2d52e8ce92c8bc044898cc289a7e96b4',1,'cub::BlockStoreDirect(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga8b5f82ad8487072b6cc80b312db1962d',1,'cub::BlockStoreDirect(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga34a623c83894408f4f05ceb788d5ac92',1,'cub::BlockStoreDirect(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]], + ['blockstoredirectstriped',['BlockStoreDirectStriped',['../group___simt_utils.html#gaa18341f23a5d00c1b148e0013a9cc637',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gaed26402e843c84978ce85da24819ebeb',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#gadcef89bcc6b3c66e1fa1267c15b08a78',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)'],['../group___simt_utils.html#ga75150e5519f86c1054d7a7584e1a4f23',1,'cub::BlockStoreDirectStriped(OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD], int stride=blockDim.x)']]], + ['blockstorevectorized',['BlockStoreVectorized',['../group___simt_utils.html#ga013c3ab8214854f45e8d678958e7dde9',1,'cub::BlockStoreVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])'],['../group___simt_utils.html#ga5db0cef20c11ea62aef484c587c4e064',1,'cub::BlockStoreVectorized(T *block_ptr, T(&items)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/functions_64.html b/docs/html/search/functions_64.html new file mode 100644 index 0000000000..17149308ab --- /dev/null +++ b/docs/html/search/functions_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_64.js b/docs/html/search/functions_64.js new file mode 100644 index 0000000000..a8f34c329c --- /dev/null +++ b/docs/html/search/functions_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['debug',['Debug',['../group___host_util.html#ga0ac6d9c9d88ac0da0d644c88a3b36aa3',1,'cub::Debug(cudaError_t error, const char *message, const char *filename, int line)'],['../group___host_util.html#ga5a175d2a88f63f7f1ab30e8b4f2cfa95',1,'cub::Debug(cudaError_t error, const char *filename, int line)']]] +]; diff --git a/docs/html/search/functions_65.html b/docs/html/search/functions_65.html new file mode 100644 index 0000000000..13260cf253 --- /dev/null +++ b/docs/html/search/functions_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_65.js b/docs/html/search/functions_65.js new file mode 100644 index 0000000000..c84bbb320c --- /dev/null +++ b/docs/html/search/functions_65.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['exclusivescan',['ExclusiveScan',['../classcub_1_1_warp_scan.html#ab034c0bd94f866b7044d085f0d354e2d',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#a7ad7b67ebb45eae6d120e55206dace8e',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#af0e55650ffbbb6ad5245c11110fc9343',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_warp_scan.html#ae84a95431640ff2d450c4b0a98dd826e',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#acb0ad5c2aaa0866aa7bcc9a597098daa',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a182cf61f1437c0ac0e3567a9737fcbfe',1,'cub::WarpScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#acc948eb8877a6d9956daebf258119b7a',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, const T &identity, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a64fbe22df260c4731536e1bbcec70cf6',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aa858e1cc0cee3e54fc3fb00bc0ecb3ca',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a2a7bf6b9e06e0ed3a71931f1694359f5',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T identity, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a86857a9daede055f69299caff5b16259',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, T identity, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a2cdb196b18b1d0eb3f7f85a57ed3ac7e',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], const T &identity, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a1a0090740c3b47eb018831f36d4fe307',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a929f90d956502a7142fa780647241bf0',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aaea795b16f8a66dbbef62952b5f73643',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#afc79e233524e1e357a4cb77c44a46957',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a05c65595bc59cf1bb0fd04965f3b0988',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#ac8d2690770ba251c6da988936f248da5',1,'cub::BlockScan::ExclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)']]], + ['exclusivesum',['ExclusiveSum',['../classcub_1_1_warp_scan.html#a2695420235a1ace8817a595a6f930d61',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_warp_scan.html#a2a7c0b9abd940adf1b76e1d5931fcfd7',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a8b9720f46d2b9cb920c4eb8a6543fc2c',1,'cub::WarpScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a01676b552903e7b5d240bbde7968d55e',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)'],['../classcub_1_1_block_scan.html#aa4b6abbc17343b897a7b93d581620164',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)'],['../classcub_1_1_block_scan.html#af0fb65e2f9663daaee32390dee4c786b',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a9adb14da21b88da067e0dae60c628183',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a8e661f683b84c496a0f1bcd96d5bb528',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_block_scan.html#a1414392abb5dc2f60386130ad8ad5130',1,'cub::BlockScan::ExclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/functions_66.html b/docs/html/search/functions_66.html new file mode 100644 index 0000000000..12565e3b2f --- /dev/null +++ b/docs/html/search/functions_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_66.js b/docs/html/search/functions_66.js new file mode 100644 index 0000000000..a09c3361bc --- /dev/null +++ b/docs/html/search/functions_66.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['flag',['Flag',['../classcub_1_1_block_discontinuity.html#ab6390151f109ac253810504ddc5a7c04',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)'],['../classcub_1_1_block_discontinuity.html#a3bdf3b7ad8ace5249f84e103f25ff3bb',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_discontinuity.html#a7fa4c2dc8bbe5db5da50fedca0613b46',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD], T &last_tile_item)'],['../classcub_1_1_block_discontinuity.html#a351ed32eaada93c944fbb29feda5a6cd',1,'cub::BlockDiscontinuity::Flag(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T tile_predecessor, FlagOp flag_op, FlagT(&flags)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/functions_69.html b/docs/html/search/functions_69.html new file mode 100644 index 0000000000..9edd1a1c1b --- /dev/null +++ b/docs/html/search/functions_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_69.js b/docs/html/search/functions_69.js new file mode 100644 index 0000000000..27182ee283 --- /dev/null +++ b/docs/html/search/functions_69.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['inclusivescan',['InclusiveScan',['../classcub_1_1_warp_scan.html#a9f0397ded5ce89a8750dc8fe10078f3e',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_warp_scan.html#a4df11b322777066e9237fc2ef3d257e5',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#ae5e4f735a2bda14ad6a94a68a0528bd1',1,'cub::WarpScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a981f9bae42f6f9c5fe6950698b97d8d4',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a0b750ea27539a71e46657f3d63fdbce6',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a4b987cb649f4aced568b77bd9ac18db6',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#aae6c7a0cdb8ea21cd7eac0cecacd1ac1',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#ac5220b7189e39eb4ff67430f732b1f96',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T input, T &output, ScanOp scan_op)'],['../classcub_1_1_block_scan.html#a046dfe9d6daa55a0d9c74d6ce2f7aa5b',1,'cub::BlockScan::InclusiveScan(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], ScanOp scan_op)']]], + ['inclusivesum',['InclusiveSum',['../classcub_1_1_warp_scan.html#adec85c76d951c326e592e364aa63c728',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_warp_scan.html#a78bf6035a0bccc58913dc0ec570c487d',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate)'],['../classcub_1_1_warp_scan.html#a032ce184b653241719effbd0b5b2dbcd',1,'cub::WarpScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &warp_aggregate, WarpPrefixOp &warp_prefix_op)'],['../classcub_1_1_block_scan.html#a738fa570c0a0e391397c342eaab388cb',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate)'],['../classcub_1_1_block_scan.html#a88a16a5a98fadb09fa216b2d234f0b86',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate)'],['../classcub_1_1_block_scan.html#aed86bb94fe1908673dadbbaec0f95362',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output, T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#a47978bae019da4e99c30519de96534a4',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD], T &block_aggregate, BlockPrefixOp &block_prefix_op)'],['../classcub_1_1_block_scan.html#af4bfc827149cbcfd741e578cfaeee5c7',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T input, T &output)'],['../classcub_1_1_block_scan.html#ae9562dc6cb1e745c8714668dcef3e5b1',1,'cub::BlockScan::InclusiveSum(SmemStorage &smem_storage, T(&input)[ITEMS_PER_THREAD], T(&output)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/functions_6c.html b/docs/html/search/functions_6c.html new file mode 100644 index 0000000000..33c0d6dd14 --- /dev/null +++ b/docs/html/search/functions_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_6c.js b/docs/html/search/functions_6c.js new file mode 100644 index 0000000000..9155e84810 --- /dev/null +++ b/docs/html/search/functions_6c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['load',['Load',['../classcub_1_1_block_load.html#ac671e9f033037fc01384a9296684200c',1,'cub::BlockLoad::Load(SmemStorage &smem_storage, InputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_load.html#ae7025d183926de0430146d41b5771032',1,'cub::BlockLoad::Load(SmemStorage &smem_storage, InputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]] +]; diff --git a/docs/html/search/functions_6f.html b/docs/html/search/functions_6f.html new file mode 100644 index 0000000000..9d6926417d --- /dev/null +++ b/docs/html/search/functions_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_6f.js b/docs/html/search/functions_6f.js new file mode 100644 index 0000000000..342970781d --- /dev/null +++ b/docs/html/search/functions_6f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['operator_28_29',['operator()',['../structcub_1_1_equality.html#a89f91d9fabb6b8237f97307ce04f1bab',1,'cub::Equality::operator()()'],['../structcub_1_1_sum.html#a05a1ac22d3e5c852dec8c39724297fe3',1,'cub::Sum::operator()()'],['../structcub_1_1_max.html#a880bd2cf50b320c1771eafe31ebf9ea1',1,'cub::Max::operator()()']]] +]; diff --git a/docs/html/search/functions_72.html b/docs/html/search/functions_72.html new file mode 100644 index 0000000000..71f58bbd14 --- /dev/null +++ b/docs/html/search/functions_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_72.js b/docs/html/search/functions_72.js new file mode 100644 index 0000000000..54fa60508c --- /dev/null +++ b/docs/html/search/functions_72.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['reduce',['Reduce',['../classcub_1_1_block_reduce.html#aee16d11eea520e487f387b7d9f2755d2',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op)'],['../classcub_1_1_block_reduce.html#acc9a5597731b4985fac1e8a90153d979',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD], ReductionOp reduction_op)'],['../classcub_1_1_block_reduce.html#aeddda91425d07c74b819d34ac5b7a0a6',1,'cub::BlockReduce::Reduce(SmemStorage &smem_storage, T input, ReductionOp reduction_op, const unsigned int &valid_threads)']]] +]; diff --git a/docs/html/search/functions_73.html b/docs/html/search/functions_73.html new file mode 100644 index 0000000000..c80660e8c3 --- /dev/null +++ b/docs/html/search/functions_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_73.js b/docs/html/search/functions_73.js new file mode 100644 index 0000000000..cbbbbf39a0 --- /dev/null +++ b/docs/html/search/functions_73.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['scattertoblocked',['ScatterToBlocked',['../classcub_1_1_block_exchange.html#a7a429434bbdc3e949a8291461a74bff9',1,'cub::BlockExchange']]], + ['scattertostriped',['ScatterToStriped',['../classcub_1_1_block_exchange.html#a8b8997367d0d42ee7eb600b981f7b72d',1,'cub::BlockExchange']]], + ['sortblocked',['SortBlocked',['../classcub_1_1_block_radix_sort.html#abdbfda59c129946222ab10d2e2e6f6f5',1,'cub::BlockRadixSort::SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#a7e304558942536fc1636849f8d93d896',1,'cub::BlockRadixSort::SortBlocked(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['sortblockedtostriped',['SortBlockedToStriped',['../classcub_1_1_block_radix_sort.html#ac7fe497d674f5da3062a3d34f010f438',1,'cub::BlockRadixSort::SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#ab1a7c9c9e536f13741b4c4f6c369ce80',1,'cub::BlockRadixSort::SortBlockedToStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['sortstriped',['SortStriped',['../classcub_1_1_block_radix_sort.html#a81e081320239182670da329c2b036166',1,'cub::BlockRadixSort::SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)'],['../classcub_1_1_block_radix_sort.html#a0c730daecd6cc6f69135ae36d11d5c53',1,'cub::BlockRadixSort::SortStriped(SmemStorage &smem_storage, KeyType(&keys)[ITEMS_PER_THREAD], ValueType(&values)[ITEMS_PER_THREAD], unsigned int begin_bit=0, const unsigned int &end_bit=sizeof(KeyType)*8)']]], + ['store',['Store',['../classcub_1_1_block_store.html#a1fc63a32e80b1275145a469e719f8530',1,'cub::BlockStore::Store(SmemStorage &smem_storage, OutputIterator block_itr, T(&items)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_store.html#a3c1f7f37767338869f44e410a90f2255',1,'cub::BlockStore::Store(SmemStorage &smem_storage, OutputIterator block_itr, const SizeT &guarded_items, T(&items)[ITEMS_PER_THREAD])']]], + ['stripedtoblocked',['StripedToBlocked',['../classcub_1_1_block_exchange.html#ad8000bf73c3ce935018f32451985ae37',1,'cub::BlockExchange']]], + ['sum',['Sum',['../classcub_1_1_block_reduce.html#a136060887c434257984b8bf3f5c62323',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T input)'],['../classcub_1_1_block_reduce.html#abe33a10ae2e316943e95d23f1d4d702a',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T(&inputs)[ITEMS_PER_THREAD])'],['../classcub_1_1_block_reduce.html#aad43736f8ea38a2c9052059b1d80c7fc',1,'cub::BlockReduce::Sum(SmemStorage &smem_storage, T input, const unsigned int &valid_threads)']]] +]; diff --git a/docs/html/search/functions_74.html b/docs/html/search/functions_74.html new file mode 100644 index 0000000000..1605901ee1 --- /dev/null +++ b/docs/html/search/functions_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_74.js b/docs/html/search/functions_74.js new file mode 100644 index 0000000000..1f3526c6fe --- /dev/null +++ b/docs/html/search/functions_74.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['threadload',['ThreadLoad',['../group___simt_utils.html#ga1e390b9fee4c8012a021d49d9b76b1e8',1,'cub']]], + ['threadstore',['ThreadStore',['../group___simt_utils.html#gad117ecb99b9230a032971b0ac08ca6dc',1,'cub']]] +]; diff --git a/docs/html/search/groups_63.html b/docs/html/search/groups_63.html new file mode 100644 index 0000000000..f4ece649de --- /dev/null +++ b/docs/html/search/groups_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/groups_63.js b/docs/html/search/groups_63.js new file mode 100644 index 0000000000..fc670c39e0 --- /dev/null +++ b/docs/html/search/groups_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['cooperative_20simt_20operations',['Cooperative SIMT Operations',['../group___simt_coop.html',1,'']]] +]; diff --git a/docs/html/search/groups_68.html b/docs/html/search/groups_68.html new file mode 100644 index 0000000000..de9940f747 --- /dev/null +++ b/docs/html/search/groups_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/groups_68.js b/docs/html/search/groups_68.js new file mode 100644 index 0000000000..8fcb135372 --- /dev/null +++ b/docs/html/search/groups_68.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['host_20utilities',['Host Utilities',['../group___host_util.html',1,'']]] +]; diff --git a/docs/html/search/groups_73.html b/docs/html/search/groups_73.html new file mode 100644 index 0000000000..d77ec54c86 --- /dev/null +++ b/docs/html/search/groups_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/groups_73.js b/docs/html/search/groups_73.js new file mode 100644 index 0000000000..7a92113dba --- /dev/null +++ b/docs/html/search/groups_73.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['simt_20primitives',['SIMT Primitives',['../group___simt.html',1,'']]], + ['simt_20utilities',['SIMT Utilities',['../group___simt_utils.html',1,'']]] +]; diff --git a/docs/html/search/mag_sel.png b/docs/html/search/mag_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..81f6040a2092402b4d98f9ffa8855d12a0d4ca17 GIT binary patch literal 563 zcmV-30?hr1P)zxx&tqG15pu7)IiiXFflOc2k;dXd>%13GZAy? zRz!q0=|E6a6vV)&ZBS~G9oe0kbqyw1*gvY`{Pop2oKq#FlzgXt@Xh-7fxh>}`Fxg> z$%N%{$!4=5nM{(;=c!aG1Ofr^Do{u%Ih{^&Fc@H2)+a-?TBXrw5DW&z%Nb6mQ!L9O zl}b@6mB?f=tX3;#vl)}ggh(Vpyh(IK z(Mb0D{l{U$FsRjP;!{($+bsaaVi8T#1c0V#qEIOCYa9@UVLV`f__E81L;?WEaRA;Y zUH;rZ;vb;mk7JX|$=i3O~&If0O@oZfLg8gfIjW=dcBsz;gI=!{-r4# z4%6v$&~;q^j7Fo67yJ(NJWuX+I~I!tj^nW3?}^9bq|<3^+vapS5sgM^x7!cs(+mMT z&y%j};&~po+YO)3hoUH4E*E;e9>?R6SS&`X)p`njycAVcg{rEb41T{~Hk(bl-7eSb zmFxA2uIqo#@R?lKm50ND`~6Nfn|-b1|L6O98vt3Tx@gKz#isxO002ovPDHLkV1kyW B_l^Jn literal 0 HcmV?d00001 diff --git a/docs/html/search/namespaces_63.html b/docs/html/search/namespaces_63.html new file mode 100644 index 0000000000..a6ca16abdd --- /dev/null +++ b/docs/html/search/namespaces_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/namespaces_63.js b/docs/html/search/namespaces_63.js new file mode 100644 index 0000000000..3567b32a4a --- /dev/null +++ b/docs/html/search/namespaces_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['cub',['cub',['../namespacecub.html',1,'']]] +]; diff --git a/docs/html/search/nomatches.html b/docs/html/search/nomatches.html new file mode 100644 index 0000000000..b1ded27e9a --- /dev/null +++ b/docs/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/docs/html/search/pages_62.html b/docs/html/search/pages_62.html new file mode 100644 index 0000000000..ea5205842a --- /dev/null +++ b/docs/html/search/pages_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/pages_62.js b/docs/html/search/pages_62.js new file mode 100644 index 0000000000..3dcb789fb8 --- /dev/null +++ b/docs/html/search/pages_62.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['bibliographic_20references',['Bibliographic References',['../citelist.html',1,'']]] +]; diff --git a/docs/html/search/search.css b/docs/html/search/search.css new file mode 100644 index 0000000000..5b208eddd8 --- /dev/null +++ b/docs/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:116px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/docs/html/search/search.js b/docs/html/search/search.js new file mode 100644 index 0000000000..1c7ea7e152 --- /dev/null +++ b/docs/html/search/search.js @@ -0,0 +1,817 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111011001111101110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110010001001110001110010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000001000010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010111001001001001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 5: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 6: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 7: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 8: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 9: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 10: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 11: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "namespaces", + 3: "files", + 4: "functions", + 5: "variables", + 6: "typedefs", + 7: "enums", + 8: "enumvalues", + 9: "defines", + 10: "groups", + 11: "pages" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var hexCode; + if (code<16) + { + hexCode="0"+code.toString(16); + } + else + { + hexCode=code.toString(16); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') + { + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; ek7RCwB~R6VQOP#AvB$vH7i{6H{96zot$7cZT<7246EF5Np6N}+$IbiG6W zg#87A+NFaX+=_^xM1#gCtshC=E{%9^uQX_%?YwXvo{#q&MnpJ8uh(O?ZRc&~_1%^SsPxG@rfElJg-?U zm!Cz-IOn(qJP3kDp-^~qt+FGbl=5jNli^Wj_xIBG{Rc0en{!oFvyoNC7{V~T8}b>| z=jL2WIReZzX(YN(_9fV;BBD$VXQIxNasAL8ATvEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/docs/html/search/search_r.png b/docs/html/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..97ee8b439687084201b79c6f776a41f495c6392a GIT binary patch literal 612 zcmV-q0-ODbP)PbXFRCwB?)W514K@j&X?z2*SxFI6-@HT2E2K=9X9%Pb zEK*!TBw&g(DMC;|A)uGlRkOS9vd-?zNs%bR4d$w+ox_iFnE8fvIvv7^5<(>Te12Li z7C)9srCzmK{ZcNM{YIl9j{DePFgOWiS%xG@5CnnnJa4nvY<^glbz7^|-ZY!dUkAwd z{gaTC@_>b5h~;ug#R0wRL0>o5!hxm*s0VW?8dr}O#zXTRTnrQm_Z7z1Mrnx>&p zD4qifUjzLvbVVWi?l?rUzwt^sdb~d!f_LEhsRVIXZtQ=qSxuxqm zEX#tf>$?M_Y1-LSDT)HqG?`%-%ZpY!#{N!rcNIiL;G7F0`l?)mNGTD9;f9F5Up3Kg zw}a<-JylhG&;=!>B+fZaCX+?C+kHYrP%c?X2!Zu_olK|GcS4A70HEy;vn)I0>0kLH z`jc(WIaaHc7!HS@f*^R^Znx8W=_jIl2oWJoQ*h1^$FX!>*PqR1J8k|fw}w_y}TpE>7m8DqDO<3z`OzXt$ccSejbEZCg@0000 + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/typedefs_73.js b/docs/html/search/typedefs_73.js new file mode 100644 index 0000000000..32307ec10b --- /dev/null +++ b/docs/html/search/typedefs_73.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['smemstorage',['SmemStorage',['../classcub_1_1_warp_scan.html#a2bfa864e963cb4965139ac1b6c66d1b7',1,'cub::WarpScan::SmemStorage()'],['../classcub_1_1_block_reduce.html#aea61e2e067e0e2d3fba2b0c8e0f73d8d',1,'cub::BlockReduce::SmemStorage()'],['../classcub_1_1_block_scan.html#abda6008896e2e17b50c7deb0ab320e64',1,'cub::BlockScan::SmemStorage()'],['../classcub_1_1_block_radix_sort.html#a495e63ab526ce35e6dfce9fb5206746c',1,'cub::BlockRadixSort::SmemStorage()'],['../classcub_1_1_block_load.html#a09296fd690f1452df9cae24a037e906a',1,'cub::BlockLoad::SmemStorage()'],['../classcub_1_1_block_store.html#aa80c1691bc7aa80bc38c2797b3a99c24',1,'cub::BlockStore::SmemStorage()'],['../classcub_1_1_block_exchange.html#ad91573946e4abe5ae5e34277ded1c215',1,'cub::BlockExchange::SmemStorage()'],['../classcub_1_1_block_discontinuity.html#a855c92f9c3869909913860fa11e755a4',1,'cub::BlockDiscontinuity::SmemStorage()']]] +]; diff --git a/docs/html/search/typedefs_74.html b/docs/html/search/typedefs_74.html new file mode 100644 index 0000000000..b2f6d2a098 --- /dev/null +++ b/docs/html/search/typedefs_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/typedefs_74.js b/docs/html/search/typedefs_74.js new file mode 100644 index 0000000000..a7b7b7106d --- /dev/null +++ b/docs/html/search/typedefs_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['type',['Type',['../structcub_1_1_if.html#af689e9527f56372e66413b65581ded8e',1,'cub::If::Type()'],['../structcub_1_1_remove_qualifiers.html#a9143e196ef5e6a0176b953f677e94671',1,'cub::RemoveQualifiers::Type()'],['../structcub_1_1_enable_if.html#aafd9405b5887d2a6d3553eee0202798a',1,'cub::EnableIf::Type()']]] +]; diff --git a/docs/html/search/variables_63.html b/docs/html/search/variables_63.html new file mode 100644 index 0000000000..422085c127 --- /dev/null +++ b/docs/html/search/variables_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_63.js b/docs/html/search/variables_63.js new file mode 100644 index 0000000000..2cfc4afb05 --- /dev/null +++ b/docs/html/search/variables_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['category',['CATEGORY',['../structcub_1_1_base_traits.html#a25ff6477c84dc3bd5f4b5e70cd600f09',1,'cub::BaseTraits']]] +]; diff --git a/docs/html/search/variables_76.html b/docs/html/search/variables_76.html new file mode 100644 index 0000000000..8af2374616 --- /dev/null +++ b/docs/html/search/variables_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_76.js b/docs/html/search/variables_76.js new file mode 100644 index 0000000000..58c39304d9 --- /dev/null +++ b/docs/html/search/variables_76.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value',['VALUE',['../structcub_1_1_log2.html#ad1923657cb57427a8621f53022590cd2',1,'cub::Log2']]] +]; diff --git a/cub/docs/images/simt_abstraction.png b/docs/html/simt_abstraction.png similarity index 100% rename from cub/docs/images/simt_abstraction.png rename to docs/html/simt_abstraction.png diff --git a/cub/docs/images/sorting_logo.png b/docs/html/sorting_logo.png similarity index 100% rename from cub/docs/images/sorting_logo.png rename to docs/html/sorting_logo.png diff --git a/cub/docs/images/striped.png b/docs/html/striped.png similarity index 100% rename from cub/docs/images/striped.png rename to docs/html/striped.png diff --git a/docs/html/structcub_1_1_array_traits.html b/docs/html/structcub_1_1_array_traits.html new file mode 100644 index 0000000000..2ac4b06ced --- /dev/null +++ b/docs/html/structcub_1_1_array_traits.html @@ -0,0 +1,124 @@ + + + + + + + +CUB: cub::ArrayTraits< ArrayType, LENGTH > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::ArrayTraits< ArrayType, LENGTH > Struct Template Reference
+
+
+

Detailed description

+

template<typename ArrayType, int LENGTH = -1>
+struct cub::ArrayTraits< ArrayType, LENGTH >

+ +

Array traits.

+

The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_base_traits-members.html b/docs/html/structcub_1_1_base_traits-members.html new file mode 100644 index 0000000000..b0887349c0 --- /dev/null +++ b/docs/html/structcub_1_1_base_traits-members.html @@ -0,0 +1,122 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits > Member List
+
+ + + + + + diff --git a/docs/html/structcub_1_1_base_traits.html b/docs/html/structcub_1_1_base_traits.html new file mode 100644 index 0000000000..c1cd723620 --- /dev/null +++ b/docs/html/structcub_1_1_base_traits.html @@ -0,0 +1,143 @@ + + + + + + + +CUB: cub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits > Struct Template Reference
+
+
+

Detailed description

+

template<Category _CATEGORY, bool _PRIMITIVE, bool _NULL_TYPE, typename _UnsignedBits>
+struct cub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits >

+ +

Basic type traits.

+
+ + + +

+Public Types

enum  { PRIMITIVE = _PRIMITIVE, +NULL_TYPE = _NULL_TYPE + }
 
+ + + + +

+Static Public Members

+static const Category CATEGORY = _CATEGORY
 Category.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_enable_if-members.html b/docs/html/structcub_1_1_enable_if-members.html new file mode 100644 index 0000000000..a4b67d1665 --- /dev/null +++ b/docs/html/structcub_1_1_enable_if-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::EnableIf< Condition, T > Member List
+
+
+ +

This is the complete list of members for cub::EnableIf< Condition, T >, including all inherited members.

+ + +
Type typedefcub::EnableIf< Condition, T >
+ + + + + diff --git a/docs/html/structcub_1_1_enable_if.html b/docs/html/structcub_1_1_enable_if.html new file mode 100644 index 0000000000..f27a140767 --- /dev/null +++ b/docs/html/structcub_1_1_enable_if.html @@ -0,0 +1,135 @@ + + + + + + + +CUB: cub::EnableIf< Condition, T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::EnableIf< Condition, T > Struct Template Reference
+
+
+

Detailed description

+

template<bool Condition, class T = void>
+struct cub::EnableIf< Condition, T >

+ +

Simple enable-if (similar to Boost)

+
+ + + + +

+Public Types

+typedef T Type
 Enable-if type for SFINAE dummy variables.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_equality-members.html b/docs/html/structcub_1_1_equality-members.html new file mode 100644 index 0000000000..73f2bee291 --- /dev/null +++ b/docs/html/structcub_1_1_equality-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Equality< T > Member List
+
+
+ +

This is the complete list of members for cub::Equality< T >, including all inherited members.

+ + +
operator()(const T &a, const T &b)cub::Equality< T >inline
+ + + + + diff --git a/docs/html/structcub_1_1_equality.html b/docs/html/structcub_1_1_equality.html new file mode 100644 index 0000000000..0f3d3a3748 --- /dev/null +++ b/docs/html/structcub_1_1_equality.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: cub::Equality< T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Equality< T > Struct Template Reference
+
+
+

Detailed description

+

template<typename T>
+struct cub::Equality< T >

+ +

Default equality functor.

+
+ + + + +

+Public Methods

+__host__ __device__
+__forceinline__ bool 
operator() (const T &a, const T &b)
 Boolean equality operator, returns (a == b)
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_equals-members.html b/docs/html/structcub_1_1_equals-members.html new file mode 100644 index 0000000000..d66c06019d --- /dev/null +++ b/docs/html/structcub_1_1_equals-members.html @@ -0,0 +1,121 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Equals< A, B > Member List
+
+
+ +

This is the complete list of members for cub::Equals< A, B >, including all inherited members.

+ + + +
NEGATE enum value (defined in cub::Equals< A, B >)cub::Equals< A, B >
VALUE enum value (defined in cub::Equals< A, B >)cub::Equals< A, B >
+ + + + + diff --git a/docs/html/structcub_1_1_equals.html b/docs/html/structcub_1_1_equals.html new file mode 100644 index 0000000000..011bff37d4 --- /dev/null +++ b/docs/html/structcub_1_1_equals.html @@ -0,0 +1,135 @@ + + + + + + + +CUB: cub::Equals< A, B > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Equals< A, B > Struct Template Reference
+
+
+

Detailed description

+

template<typename A, typename B>
+struct cub::Equals< A, B >

+ +

Type equality test.

+
+ + + +

+Public Types

enum  { VALUE = 0, +NEGATE = 1 + }
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_if-members.html b/docs/html/structcub_1_1_if-members.html new file mode 100644 index 0000000000..fff13226e7 --- /dev/null +++ b/docs/html/structcub_1_1_if-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::If< IF, ThenType, ElseType > Member List
+
+
+ +

This is the complete list of members for cub::If< IF, ThenType, ElseType >, including all inherited members.

+ + +
Type typedefcub::If< IF, ThenType, ElseType >
+ + + + + diff --git a/docs/html/structcub_1_1_if.html b/docs/html/structcub_1_1_if.html new file mode 100644 index 0000000000..b74d319216 --- /dev/null +++ b/docs/html/structcub_1_1_if.html @@ -0,0 +1,135 @@ + + + + + + + +CUB: cub::If< IF, ThenType, ElseType > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::If< IF, ThenType, ElseType > Struct Template Reference
+
+
+

Detailed description

+

template<bool IF, typename ThenType, typename ElseType>
+struct cub::If< IF, ThenType, ElseType >

+ +

Type selection (IF ? ThenType : ElseType)

+
+ + + + +

+Public Types

+typedef ThenType Type
 Conditional type result.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_is_volatile-members.html b/docs/html/structcub_1_1_is_volatile-members.html new file mode 100644 index 0000000000..d53af4b367 --- /dev/null +++ b/docs/html/structcub_1_1_is_volatile-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::IsVolatile< Tp > Member List
+
+
+ +

This is the complete list of members for cub::IsVolatile< Tp >, including all inherited members.

+ + +
VALUE enum value (defined in cub::IsVolatile< Tp >)cub::IsVolatile< Tp >
+ + + + + diff --git a/docs/html/structcub_1_1_is_volatile.html b/docs/html/structcub_1_1_is_volatile.html new file mode 100644 index 0000000000..519f242133 --- /dev/null +++ b/docs/html/structcub_1_1_is_volatile.html @@ -0,0 +1,134 @@ + + + + + + + +CUB: cub::IsVolatile< Tp > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::IsVolatile< Tp > Struct Template Reference
+
+
+

Detailed description

+

template<typename Tp>
+struct cub::IsVolatile< Tp >

+ +

Volatile modifier test.

+
+ + + +

+Public Types

enum  { VALUE = 0 + }
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_log2-members.html b/docs/html/structcub_1_1_log2-members.html new file mode 100644 index 0000000000..e7cccc6131 --- /dev/null +++ b/docs/html/structcub_1_1_log2-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Log2< N, CURRENT_VAL, COUNT > Member List
+
+
+ +

This is the complete list of members for cub::Log2< N, CURRENT_VAL, COUNT >, including all inherited members.

+ + +
VALUEcub::Log2< N, CURRENT_VAL, COUNT >static
+ + + + + diff --git a/docs/html/structcub_1_1_log2.html b/docs/html/structcub_1_1_log2.html new file mode 100644 index 0000000000..45e5ef6dda --- /dev/null +++ b/docs/html/structcub_1_1_log2.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: cub::Log2< N, CURRENT_VAL, COUNT > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Log2< N, CURRENT_VAL, COUNT > Struct Template Reference
+
+
+

Detailed description

+

template<int N, int CURRENT_VAL = N, int COUNT = 0>
+struct cub::Log2< N, CURRENT_VAL, COUNT >

+ +

Statically determine log2(N), rounded up.

+

For example: Log2<8>::VALUE // 3 Log2<3>::VALUE // 2

+
+ + + + +

+Static Public Members

+static const int VALUE = Log2<N, (CURRENT_VAL >> 1), COUNT + 1>::VALUE
 Static logarithm value.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_max-members.html b/docs/html/structcub_1_1_max-members.html new file mode 100644 index 0000000000..22cea2bafc --- /dev/null +++ b/docs/html/structcub_1_1_max-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Max< T > Member List
+
+
+ +

This is the complete list of members for cub::Max< T >, including all inherited members.

+ + +
operator()(const T &a, const T &b)cub::Max< T >inline
+ + + + + diff --git a/docs/html/structcub_1_1_max.html b/docs/html/structcub_1_1_max.html new file mode 100644 index 0000000000..effbd73321 --- /dev/null +++ b/docs/html/structcub_1_1_max.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: cub::Max< T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Max< T > Struct Template Reference
+
+
+

Detailed description

+

template<typename T>
+struct cub::Max< T >

+ +

Default max functor.

+
+ + + + +

+Public Methods

+__host__ __device__
+__forceinline__ T 
operator() (const T &a, const T &b)
 Boolean max operator, returns (a > b) ? a : b
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_null_type.html b/docs/html/structcub_1_1_null_type.html new file mode 100644 index 0000000000..510c424066 --- /dev/null +++ b/docs/html/structcub_1_1_null_type.html @@ -0,0 +1,121 @@ + + + + + + + +CUB: cub::NullType Struct Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::NullType Struct Reference
+
+
+

Detailed description

+

A simple "NULL" marker type.

+

The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_numeric_traits-members.html b/docs/html/structcub_1_1_numeric_traits-members.html new file mode 100644 index 0000000000..027c782222 --- /dev/null +++ b/docs/html/structcub_1_1_numeric_traits-members.html @@ -0,0 +1,122 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::NumericTraits< T > Member List
+
+ + + + + + diff --git a/docs/html/structcub_1_1_numeric_traits.html b/docs/html/structcub_1_1_numeric_traits.html new file mode 100644 index 0000000000..76f032e61b --- /dev/null +++ b/docs/html/structcub_1_1_numeric_traits.html @@ -0,0 +1,147 @@ + + + + + + + +CUB: cub::NumericTraits< T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::NumericTraits< T > Struct Template Reference
+
+
+

Detailed description

+

template<typename T>
+struct cub::NumericTraits< T >

+ +

Numeric type traits.

+
+Inheritance diagram for cub::NumericTraits< T >:
+
+
+ + +cub::BaseTraits< NOT_A_NUMBER, false, false, T > + +
+ + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from cub::BaseTraits< NOT_A_NUMBER, false, false, T >
enum  
 
- Static Public Members inherited from cub::BaseTraits< NOT_A_NUMBER, false, false, T >
+static const Category CATEGORY
 Category.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_numeric_traits.png b/docs/html/structcub_1_1_numeric_traits.png new file mode 100644 index 0000000000000000000000000000000000000000..39396980c2a8ed07a4b04c7689d2a4e45539c046 GIT binary patch literal 968 zcmeAS@N?(olHy`uVBq!ia0y~yU^EA^12~w0q<7V!Fd!un;1lBd|Nnm=^TnI5rTvE{ z09jys;J^Xa&O7ozE=Ng_UoZnu5eQs86=KA|z#Q)B;uuoF_;&8=qEA)=EYXWs?fI`< z-;ny6tHO`<&_c7PYST(LUWr@#Z&L9&$8(m^6I3-Ps5F02^R#>DJE`W-Y?Yra=ANH+ zKGrR5eLY|0?44C@r@S+7R#jL0)~$VZ?{D?)hqDsbZ@(+B+Va|?xjW})ZH{`7na>}; zZ&gIK^|4GgnW^PM*74?+$3M58s@w4F-;WzA?P)di2}H z?YDKARJLAMTe`0Fqa|B@Ec^M}g1yJD+_s#b|M^O^@lm70-(J1Cb?9MkV0^Y;mG!Yb z&)3>mNawHS+?jhTD0$0gvzN0!M_=7|FTZ(p zm%Y6FHS^QL?H`vE?6tko{5tuc&urt5Vaq~3-@bI)YX4nN(bziceJ_96#8%GcYt(%D zx3Dgo?{w9?cS`-cCPjxme;Igx#q^N%na=Y+T~qByo10uGZJuqvut!6VBkTu0yQJN7K!mruH;tz`m?82Z2#YV z;n)3Y=_@K3>sEfMl6|_Y^kQX8=G%zbCI4pa4%ez#yWKN>_S|<7FPchb3b1GHUGVN- z>9c>QqVLY;d=@0qP##p^1Q-M@A}%I#k?Yxb=Jk*fPL z=WqL&`{mozpKmRsy;I&w7w}AtyHz)@>}cZrckHjr=PhTr4-8HmA*XjQ$V<~hQ?n+a literal 0 HcmV?d00001 diff --git a/docs/html/structcub_1_1_remove_qualifiers-members.html b/docs/html/structcub_1_1_remove_qualifiers-members.html new file mode 100644 index 0000000000..099a1e36a4 --- /dev/null +++ b/docs/html/structcub_1_1_remove_qualifiers-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::RemoveQualifiers< Tp, Up > Member List
+
+
+ +

This is the complete list of members for cub::RemoveQualifiers< Tp, Up >, including all inherited members.

+ + +
Type typedefcub::RemoveQualifiers< Tp, Up >
+ + + + + diff --git a/docs/html/structcub_1_1_remove_qualifiers.html b/docs/html/structcub_1_1_remove_qualifiers.html new file mode 100644 index 0000000000..95ecac96fe --- /dev/null +++ b/docs/html/structcub_1_1_remove_qualifiers.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: cub::RemoveQualifiers< Tp, Up > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::RemoveQualifiers< Tp, Up > Struct Template Reference
+
+
+

Detailed description

+

template<typename Tp, typename Up = Tp>
+struct cub::RemoveQualifiers< Tp, Up >

+ +

Removes const and volatile qualifiers from type Tp.

+

For example: typename RemoveQualifiers<volatile int>::Type // int;

+
+ + + + +

+Public Types

+typedef Up Type
 Type without const and volatile qualifiers.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_sum-members.html b/docs/html/structcub_1_1_sum-members.html new file mode 100644 index 0000000000..4a513b4903 --- /dev/null +++ b/docs/html/structcub_1_1_sum-members.html @@ -0,0 +1,120 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Sum< T > Member List
+
+
+ +

This is the complete list of members for cub::Sum< T >, including all inherited members.

+ + +
operator()(const T &a, const T &b)cub::Sum< T >inline
+ + + + + diff --git a/docs/html/structcub_1_1_sum.html b/docs/html/structcub_1_1_sum.html new file mode 100644 index 0000000000..f7ae9a117c --- /dev/null +++ b/docs/html/structcub_1_1_sum.html @@ -0,0 +1,136 @@ + + + + + + + +CUB: cub::Sum< T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Sum< T > Struct Template Reference
+
+
+

Detailed description

+

template<typename T>
+struct cub::Sum< T >

+ +

Default sum functor.

+
+ + + + +

+Public Methods

+__host__ __device__
+__forceinline__ T 
operator() (const T &a, const T &b)
 Boolean sum operator, returns a + b
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_traits-members.html b/docs/html/structcub_1_1_traits-members.html new file mode 100644 index 0000000000..51ad3ec906 --- /dev/null +++ b/docs/html/structcub_1_1_traits-members.html @@ -0,0 +1,122 @@ + + + + + + + +CUB: Member List + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
cub::Traits< T > Member List
+
+ + + + + + diff --git a/docs/html/structcub_1_1_traits.html b/docs/html/structcub_1_1_traits.html new file mode 100644 index 0000000000..3e284f8dd6 --- /dev/null +++ b/docs/html/structcub_1_1_traits.html @@ -0,0 +1,148 @@ + + + + + + + +CUB: cub::Traits< T > Struct Template Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
cub::Traits< T > Struct Template Reference
+
+
+

Detailed description

+

template<typename T>
+struct cub::Traits< T >

+ +

Type traits.

+
+Inheritance diagram for cub::Traits< T >:
+
+
+ + +cub::NumericTraits< RemoveQualifiers< T >::Type > +cub::BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type > + +
+ + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from cub::BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type >
enum  
 
- Static Public Members inherited from cub::BaseTraits< NOT_A_NUMBER, false, false, RemoveQualifiers< T >::Type >
+static const Category CATEGORY
 Category.
 
+
The documentation for this struct was generated from the following file: +
+ + + + + diff --git a/docs/html/structcub_1_1_traits.png b/docs/html/structcub_1_1_traits.png new file mode 100644 index 0000000000000000000000000000000000000000..64a84269f4a160f567a1e134e8e8bc9c535287e4 GIT binary patch literal 1763 zcmcJQdr;C@6vuz&MCM~{bhlD8cUF=$N~QHtlv!%4SXz-HNnoZ_l8?+))WR|gGp!6? z4W(@u$qda0u7Z!u%9cVjK@bC$cBVgeXLkSD*)wy_{oXm}&YV9!=iJQw z0X`;%mWBWTm>_+u6m&;wA zIclT38vKF^I0)#9zL?;7;AQ{-okn`^3QW?I6p2pHSDP)zW>vLlZDV-|C##6==G5sd zD2#rM|JdNfu||3xYOg&Va^VN$&(!`S3~HVUHor7#xC%n(K(Dt4L(zq0vuY^PR#A3; z4ozFY!=zgFM0Q)ugvfXeMXeDU!*7LeDt@63xw9gxu(UW?8a=}j_$6bhau`^g z@u-%^$E_O2Pn9{ut_o!Ts;PZ|cxGKwfVi4$C&^1>Mc*pMT3-vQSAE1=+c{r5$L!VI zYf?ke83b>}-R`b2c;wAiwv^mO^!4;9Lo~oKW3F4Qp29b;3yBuISQhWtdo+Q%)oTdM zYa4|Qn!-6n51st(q^)2~-p+1zKI}K;zt;4Shp2w`iXg*$Aeg?{3Q`AufdXY zaLrrWhL0O`^brRZlR-12&neZEHQ%s`c;bamw1(;6ZW-PkiQ;ooo^-sJ93>VZNxoVE z2N8NM_kf78FH8JW7q?d`s1%%3h)GVd(IVXgrn^=9e3&YdlxQ8;l=i zkS$}NgFTD#9X{liFq&LSkG|eOHpccxyj{rKW7xajyl{<~XZS8uQdJPrj~jJ^N}FyI z+af)Ba|$4pZ{0AssZDmp4I7cci?%2aZWY7=`H1`G9kq1zUx;ehfE=j}LO$>06Yc3Y zQGQ+eT$@QFE&ypq>rvcSX+ z?)~|w;SD=ob!l+Je@$O)i>UwiA@Cq1SQz=|L+Y*g-70A14tBq6I(#1zK^Q*+{yZd$ zsu&qu=jPkLwCIMG(t{I2sfc&zP)lX0g6^d_W$Ea!kE%I1ej>r00cOXC7B+z%uQS6Y zkG;kzhX_l38f~-4RjiJ`Oz9ZtV_GO*{pd1ZAzxBT@;VjnEFn`<-mV~{x5Z_BTYNXp zpOiql#UE#O#_zvltMroQrtz-ls_r@jR6YQ=T0?7lk}>K&Ei-lEWI_&DG56$v`Ky83 z!}ie&NzMEKQ0h^6M2rb1=iSmvC$e;jqk%D8wmP85Ap3MdJ@1A!6x&4SJ8ZkirVO<< zse?S|b7V4TCcV*p^%5plq3W)_Hqy)z(kf!0*sUvDXiHwx(-w`PJ#vhRWA=x|kC-vr z+VM>I`(tZna?++aDbx^~QHGl9kH3v0hXmdk*fZJ3LDbXU;nh8EBAL`kIFGS8CUK2v ztF(xtrm>ZltT5Ri=RP>nky#>{H%K>)-x6@IRB7z8qnmOqrXR{RDu`Ma#|rVYFUv!H0%m=b%bbABFLa$H zAA;?4(BWg@RykytW2oaRqv(I)>nprdj)!ms1bBDd#>^vnPC(?}Aif%bo;q3}H?8Pp zI%B2PFm5?@Sd7`u+*SipZr?E>whRZe-#Sl*{MJZnJ{Qp5kJd{y%IJ}Ys~M!XIp~+{foSRp1DrGxNc+Cp#nlzhZZn? X!=8FtUXi5xkpSfG0Pp*rM=tyUfADU8 literal 0 HcmV?d00001 diff --git a/docs/html/sync_off.png b/docs/html/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/docs/html/sync_on.png b/docs/html/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/docs/html/tab_a.png b/docs/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/docs/html/tab_b.png b/docs/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/docs/html/tabs.css b/docs/html/tabs.css new file mode 100644 index 0000000000..9cf578f23a --- /dev/null +++ b/docs/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/docs/html/thread__load_8cuh.html b/docs/html/thread__load_8cuh.html new file mode 100644 index 0000000000..df835ca18f --- /dev/null +++ b/docs/html/thread__load_8cuh.html @@ -0,0 +1,151 @@ + + + + + + + +CUB: thread_load.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
thread_load.cuh File Reference
+
+
+
#include <cuda.h>
+#include <iterator>
+#include "../ptx_intrinsics.cuh"
+#include "../type_utils.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + +

+Enumerations

enum  cub::PtxLoadModifier {
+  cub::PTX_LOAD_NONE, +cub::PTX_LOAD_CA, +cub::PTX_LOAD_CG, +cub::PTX_LOAD_CS, +
+  cub::PTX_LOAD_CV, +cub::PTX_LOAD_LDG, +cub::PTX_LOAD_VS +
+ }
 Enumeration of PTX cache-modifiers for memory load operations. More...
 
+ + + + + + +

+Functions

Thread utilities for memory I/O using PTX cache modifiers
template<PtxLoadModifier MODIFIER, typename InputIterator >
__device__ __forceinline__
+std::iterator_traits
+< InputIterator >::value_type 
cub::ThreadLoad (InputIterator itr)
 Thread utility for reading memory using cub::PtxLoadModifier cache modifiers. More...
 
+

Detailed Description

+

Thread utilities for reading memory using PTX cache modifiers.

+
+ + + + + diff --git a/docs/html/thread__store_8cuh.html b/docs/html/thread__store_8cuh.html new file mode 100644 index 0000000000..153c55ea76 --- /dev/null +++ b/docs/html/thread__store_8cuh.html @@ -0,0 +1,147 @@ + + + + + + + +CUB: thread_store.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
thread_store.cuh File Reference
+
+
+
#include <cuda.h>
+#include "../ptx_intrinsics.cuh"
+#include "../type_utils.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + + +

+Enumerations

enum  cub::PtxStoreModifier {
+  cub::PTX_STORE_NONE, +cub::PTX_STORE_WB, +cub::PTX_STORE_CG, +cub::PTX_STORE_CS, +
+  cub::PTX_STORE_WT, +cub::PTX_STORE_VS +
+ }
 Enumeration of PTX cache-modifiers for memory store operations. More...
 
+ + + + + + +

+Functions

Thread utilities for memory I/O using PTX cache modifiers
template<PtxStoreModifier MODIFIER, typename OutputIterator , typename T >
__device__ __forceinline__ void cub::ThreadStore (OutputIterator itr, const T &val)
 Thread utility for writing memory using cub::PtxStoreModifier cache modifiers. More...
 
+

Detailed Description

+

Thread utilities for writing memory using PTX cache modifiers.

+
+ + + + + diff --git a/cub/docs/images/tile.png b/docs/html/tile.png similarity index 100% rename from cub/docs/images/tile.png rename to docs/html/tile.png diff --git a/cub/docs/images/transpose_logo.png b/docs/html/transpose_logo.png similarity index 100% rename from cub/docs/images/transpose_logo.png rename to docs/html/transpose_logo.png diff --git a/docs/html/type__utils_8cuh.html b/docs/html/type__utils_8cuh.html new file mode 100644 index 0000000000..ebc79c3917 --- /dev/null +++ b/docs/html/type__utils_8cuh.html @@ -0,0 +1,215 @@ + + + + + + + +CUB: type_utils.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
type_utils.cuh File Reference
+
+
+
#include <iostream>
+#include "ns_wrapper.cuh"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

struct  cub::ArrayTraits< ArrayType, LENGTH >
 Array traits. More...
 
struct  cub::BaseTraits< _CATEGORY, _PRIMITIVE, _NULL_TYPE, _UnsignedBits >
 Basic type traits. More...
 
struct  cub::EnableIf< Condition, T >
 Simple enable-if (similar to Boost) More...
 
struct  cub::Equals< A, B >
 Type equality test. More...
 
struct  cub::If< IF, ThenType, ElseType >
 Type selection (IF ? ThenType : ElseType) More...
 
struct  cub::IsVolatile< Tp >
 Volatile modifier test. More...
 
struct  cub::Log2< N, CURRENT_VAL, COUNT >
 Statically determine log2(N), rounded up. More...
 
struct  cub::NullType
 A simple "NULL" marker type. More...
 
struct  cub::NumericTraits< T >
 Numeric type traits. More...
 
struct  cub::RemoveQualifiers< Tp, Up >
 Removes const and volatile qualifiers from type Tp. More...
 
struct  cub::Traits< T >
 Type traits. More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+ + + +

+Macros

#define CUB_HAS_NESTED_TYPE(detect_struct, nested_type_name)
 
+ + + + +

+Enumerations

enum  cub::Category { NOT_A_NUMBER, +SIGNED_INTEGER, +UNSIGNED_INTEGER, +FLOATING_POINT + }
 Basic type traits categories.
 
+

Detailed Description

+

Common type manipulation (metaprogramming) utilities

+

Macro Definition Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CUB_HAS_NESTED_TYPE( detect_struct,
 nested_type_name 
)
+
+Value:
template <typename T> \
+
struct detect_struct \
+
{ \
+
template <typename C> \
+
static char& test(typename C::nested_type_name*); \
+
template <typename> \
+
static int& test(...); \
+
enum \
+
{ \
+
VALUE = sizeof(test<T>(0)) < sizeof(int) \
+
}; \
+
};
+

Allows the definition of structures that will detect the presence of the specified type name within other classes

+ +
+
+
+ + + + + diff --git a/docs/html/warp__scan_8cuh.html b/docs/html/warp__scan_8cuh.html new file mode 100644 index 0000000000..3372a112e6 --- /dev/null +++ b/docs/html/warp__scan_8cuh.html @@ -0,0 +1,137 @@ + + + + + + + +CUB: warp_scan.cuh File Reference + + + + + + + + + + + + +
+
+ + + + + + +
+
CUB +
+
+
+ + + + + + + + +
+ +
+ + +
+
+ +
+
warp_scan.cuh File Reference
+
+
+
#include "../thread/thread_load.cuh"
+#include "../thread/thread_store.cuh"
+#include "../device_props.cuh"
+#include "../type_utils.cuh"
+#include "../operators.cuh"
+#include "../ns_wrapper.cuh"
+
+ + + + +

+Classes

class  cub::WarpScan< T, WARPS, LOGICAL_WARP_THREADS >
 WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+warp_scan_logo.png +
+.
+ More...
 
+ + + + +

+Namespaces

namespace  cub
 CUB namespace.
 
+

Detailed Description

+

cub::WarpScan provides variants of parallel prefix scan across a CUDA warp.

+
+ + + + + diff --git a/cub/docs/images/warp_scan_logo.png b/docs/html/warp_scan_logo.png similarity index 100% rename from cub/docs/images/warp_scan_logo.png rename to docs/html/warp_scan_logo.png diff --git a/docs/images/block_load_logo.png b/docs/images/block_load_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..da484d29aba750b9482ddf401e29591d64d80585 GIT binary patch literal 10916 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 literal 0 HcmV?d00001 diff --git a/docs/images/block_reduce.png b/docs/images/block_reduce.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3a4a6b15a1f72e63b80c8be8b8e97d34dbea5a GIT binary patch literal 35067 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 literal 0 HcmV?d00001 diff --git a/docs/images/block_scan_raking.png b/docs/images/block_scan_raking.png new file mode 100644 index 0000000000000000000000000000000000000000..48f6c55087c7c4fa6edefd8bed1c3902013c321a GIT binary patch literal 62170 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
    x8Sp4zNawzCRY>+Z-)-iq!1h&g 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ų&Fk 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%0AkpUK-FCOEYmi_hudMY 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 YQ{(ww=C1&sXp%j71btYlWcL2Q0Zw=X$N&HU literal 0 HcmV?d00001 diff --git a/docs/images/blocked.png b/docs/images/blocked.png new file mode 100644 index 0000000000000000000000000000000000000000..02d0d8464dec70c3b4a2e7c234c76167d72a211e GIT binary patch literal 2412 zcmZ8jdpy(YAOEgl<~CGvolu>*D;j2VIjyE)sf@@$63(>Fii}xi>7-S^gqGY+(vjP7 z4Y{|u&I}QCa4@;cl*@5TI@9m>&-wlFe4fwe^SqwV=ktD^*YkNlELQ?fUPfI8008-u zj@UB*0Fn~xj?z1FkK*}9;t3Rb2KOUS)TKEqHY9=^TpR$PG+uV=f~44nQXD-)0YIT~ zXMpx1@G)W^=p@#`Ey72X;p^z;soBQBKXSARJfw>}?xIs^sMLRK{1^jH`suD@-jg4q zcq(OfD+gMn9Gu3^hD>&-a~mw&;uD-;Un5ly8tMMEr(OR~C9L3b;GGgh>hxM#XpT+j z(c#IidXMh4-5)S(sqZ%gDWlfYYqg;{!l!#A0N{{JKNSFYF&qFW`9JZwGrzelURz(8 z^=4)Up=EsyyIN1*NbE|t)*BK`b*9bo*@k7J?2A3Yk5DL7@N92(Ie7?~UtFBS=i{wc zeV?SJW-TsWO-)b#y&~j2zaau`GL1wS8?!^reNe64+EEB2quCM4o60ZmjFDw$Q;2;^iaUBlBwjwCqiwL-^9l?AgJptK&B{Hs+<^f#DC?bTnfd z?c(g5`|d+_MFo3sa4=x%VMl>Sall6DpLuzC&$wI%HRHft@Rjg~P`UK8!hLrY5|VZw zNxyHQ%$BOV9blba;yq9Czq{KNeY{H&F0_BFjCKkpk+QnF2q*ubBtF3NQu?M$=GzhwIHeQ}P42dcwG>h+9o zJ{9wqCi(0Sjq^J1x%~wm%gCgu(BDwk@fCqN_4OIH^z}@y)iVDU8C2v_z+*5}&O4F5 zI`8>nE)qLdbH&?!Eh~=*x{o9M_Y|=R4*?lb%zwn?lXBa))d#T6jgoW zOXb#fweab{%bUM%m0?58 zH?C*K6)PMtQ~kv0RcqjZIbblvz-+E$3&yA8LcpS1$cXXL;R5P-U+NCqsL2^ z_wac)jvp`50V(M8>MNl)J&_Y!e-CBGhPtgvb!+%S9NF^ z8NKQaA!K|zZzb|; z{rCRT8PrKd`4!FQPorI3U_v^@*%dwZ!#7g@iu4ZDWhYj!jijvl%v#^;+c$T~RO0$U zR7$pY%6v`{<(7XQBZ2ayW;1Cn#-_^sMJ%Kn^^hYBRzXryx7W##o>G$!Aq6$3AblX} z)p9Jcj5YU>j@_oo{Q6^GNgh^5YGb#t=y4)Iapfpc$K26)#ADq+0F3IGZ0?_I_Tft=Sxl3s93+MFuy~Dje!#xMrY<2O zK#*~PM)M+1YG|`J>k=;eU+V~6pgGo?Ews&k$z0Z_y@af3{w@VQdhv5xy6FXV@!N58 zckgX(zBSLY1EGd9ypXxg&m$8R>ltx~q$tW`achUfUWAfKj&>V9c=VA4nvfQKe@kZ? zhd1|`mG!hn#3gWC-QB1B{CI~boBQxC+6OkO#=3Mio45v&qX*|cwA?G}q?TSSGM`BN z&Gv*pbguT(JmT=tqsPJEyuZ^MiLfTdX%eCU zRKq`w6#nGu2S-QPbNyT^4Gj#+KS~S4RLD+FE>J<6QG|G6qeip;VWrYvMr|u_cD6S* zu}Miui5Gj-B1%xanu_z{MojO2_bwl^x%i<)HU+~zM+&BaU^E+E>S1wqJ}nLRwuSHg zD!aI-=!KXND`JQO4SLpCeM?L)(D1^-!euXm#c?G3 z<<(NB3uBEg?VmRnMMJN8xgjLd6b5q}g3%I0eu?mLx3IJf+9lzuAMAZXkkGd!Wn`)~ zzK?;!#a#}~98a8Qf+5=;G2?j?%hTQF88?d+#zW1w2x!|^%;X1)yBjWbs0>U^$9GVO zMB=yFvrVzK3ZJW$0YFxkYAXToG^FLk`oBbs=ACUxGV31qXSPYQ_=g0XJWjwC{pfe| EA86`qh5!Hn literal 0 HcmV?d00001 diff --git a/cub/docs/images/cnp_abstraction.png b/docs/images/cnp_abstraction.png similarity index 100% rename from cub/docs/images/cnp_abstraction.png rename to docs/images/cnp_abstraction.png diff --git a/cub/docs/images/cub.png b/docs/images/cub.png similarity index 100% rename from cub/docs/images/cub.png rename to docs/images/cub.png diff --git a/docs/images/cub_overview.png b/docs/images/cub_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..8a27c39f8560ec5de02164ca4c2eabbfc0f5dc81 GIT binary patch literal 34776 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%0Di|o%yK0z7*}mW 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�xuWH!9 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 b(;jC&D)Z=*wWuB77YSsBu|`)IyWjsW$kG%E literal 0 HcmV?d00001 diff --git a/docs/images/download-icon.png b/docs/images/download-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..529e9c28d18d2cceab9faffc5c2c957c0a5db1ca GIT binary patch literal 1699 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DinK$vl=HlH+5P_o1|q9iy!t)x7$D3!r6B|j-u!8128JvAsb zF{QHbWU37V1G7?QNJL45ua8x7ey(03NR3`aZUIm?1A~oyML}Y6c4~=2Qfhi;o~_dR z-TRdkGE;1o!cBb*d<&dYGcrA@ic*8C{6dnevXd=SlDRT8R{7to0yxM>nIo* z7#ips80i}t=^C0_85>y{7$`u26417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM>v0i>r zy1t>Mr6tG=BO_g)3fZE`@j@ zw*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1;IHa;5RX-@TIKQ+g z85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;2dnK;G3A7nFr#7)%*HddFB-Y_G;}qzaI!RTG&M9cGk0|~HZV1V>2=9Z zF3nBND}m`vLFjeHsTY(KatnYqyQCInmZhe+73JqDfW2&$iQ6rfIL(9VO~LIJN1S@~ zfsWA!MJ!T8!-RmT2gHOYTObFX@Kf`Esl5o8te56G*)lLNJ@s^P42f`mJKf&@Re;1X zdA*S4k5avS1{Rha_YS^TqS&G^OF+H!5w`~C!6ROeo~7@&$gM2TaJXl2o|=V(kYQnf zyG+8zcza^29hpnS*vC!Dsn`M+&!-!8PBrp4T|dbM^;T->4vouJL>J-xk& zMMXlw!oqvbGCwJ@6yah$bLLD!Ny(J*FI_<^TQ+YtwwUYZlB44Qg)NuX5QoY`jpBus!9-jdyRv zrWkcp?)~tpOELJ;uUkvrMhBcZ@*sAno5gI`uyBd%+HpsWjxIYsA?l(@!_}9 zh4nXCoXJb}nxyb@)}gX*0tXj|zL{UH=%BpwzTCg(54)ELM#UeSpt5+;*Q+ZWrnPO@ zBj;rGsQLWyFY4>R?(NTHFzSz({HvflPtt3$_L?x!6M2E_y`z+ET=wo4UB=jVSy9E+ zTuxqo=e$$B$JnOM|6;X$hKojRkIij;j;6A0+h?$CSilvkm948R-tqhIhu@ELUhAfM zrn*O6xV5WIZb6-BuTE>wjgI|1PrGwAeB}D}d)fM~ni}Sn7li6IzI9u%zwaf-j_o)8 zZgJhXVZ#E=bM0TRR#wiQ;vTcQ`__%(%}w>Ip&%OjM{xAv->EbE5Q`Gx{_ z9xI-x(YI(wH`BISxR{}(A&Mg}&+2yc*p|h|M-sK=;UgKPcI%Z+}OUH;o*th3 zCo!Cu*~IYt@=1nkn-?*>xpRf#)SNbk_m6Hf9Gh0l@bTFLh6CLN3@2x|Fr1#>$?)jp zUWUD`nGDCK)?&D0RA4j&MnizUA;8GUCM^mDtU`>8j516}fQ^xn6N$?t$H*uNq@Mn-n1AuzrG8XrX-sGp08mx~Xkp9yL{ rP!YsFu>D*hJwU!7)F?0|#mLBy#FrHTI!jC#=09Nxuscx*N<$j}>fcKZ literal 0 HcmV?d00001 diff --git a/docs/images/favicon.png b/docs/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..48be9895643641f1887e53b07f7c30bd22f05381 GIT binary patch literal 437 zcmV;m0ZRUfP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ZK_kK~y+TWBmXB zKLaU%5u)MF;}6F#K7aD^3s$`{;yiZ7((;mgKv|H6i??3SSbZ74HH?f5+2Q)y%EC-Q zb(;>{Bj_lgJ2vdU3slAe#P2@+fNSuumUpv|=i~s1KYsan*YQVZuD*oGzWMMSNP=vD zgJ2gGe+OlVY9Npm=S>dKHqjPGR)f$WD#YnxE(b9s03jQ(8WTMNie}grbrS#0vn0}Nm}^|$p`@^lS~E)a4cWa zE>?>~#06XG;>RwvMT%WLT7k%yf|3<17F^jysy(2Ut=ioM4eL&<*!{8WoO9>i_nzl@ z-sj%;oijB_iLtIOJ}v+NxJu(Ba&iXkV}%p>HkOq9L{1c=JXQp>S$${8fSMB}ivoZz zYky@^y++0>^>ObQ0f5$LACyBOG&;Gtj)+zg$=FV!NQEOnlm^R2Kq;!qLF9-^Q*0PS zA^^aVp-oW|O4)COY7Awm>=>2_)st)hh=?@lRqA|%0JD)Ctqx}V{p)T9sMWv>1y2Ua z^kO7e8&`rO$t8&?>XLl5K*NZ93yd%cNdXigRG4j$nDIhaNUrVMYzFuOLgd4Y zpG_%cNuU_R5s=4%m}-a*fqV{&6SgTlJUkTSLL7(q%6uxoI+OcKE~7V8L=iK#ONEGbA3qZ-%h z2`#1r?TV^wtdM{iq|={|fa+h#>WnY1iM%kjNu_6VSdjflOF)_I|3gvq71~J1kzf4& zPhn$9u^wT|5hGTJtI5Lc46vut3&l91A}~A!!wQyeF)0@#Fk>#J2gS)eP^MCAb@uoL zUM3Stbw)y^QzKFd%pet5TCGMHE)j*tL`g)OxY1$`Cz`WaB!HrL96mohIw}m}@t3#~ zOkIc~I%0{d`GqT9mTPYXR8MA>Ah>oHqKUyV6nt@Hp>}yMf@Sqyay83)iCUJ+Ce5(z zh5fHWFKv0mQ9jf7*5C z+q^CR#BcUaJYUG;|I5c{<#Y+YU#qsFIdag2=H`Z!m1VY_KK)1=W-2XBkVy9Isjhx> zgnIVexqCKSTDDr8**0Mrn;Q8OJ+Xj~(kJ2;wI#O|!Q59GFeAgm(}<3yEF4Hp_1LZcgxe#Y{^+Uv1cLk;lr`(cFj#sGqhT5eZUp{ zfI^}0bz8aej_%Xu=FOPFP)FI3lw>iO`iF;QH(Xb_x!q7-@Ka`FobN zeIt^Rm!E&)i!Wr4pFD}|bIx<{3mY37BX(;v#{&Zc^{(X!@g%su$vVw}Aj>zR^m2o5 zbb9*a2Xwdh58&IkZ*Ouw@I07*y{@rQ+Q^&nu!wHwRa8`%&1MFV$NRhihGBVTCVL18 z2nh+SOy2BO-GK*&J7I2r1tII>oVt6hho@i z-q;H3#Z#v~%y0J=cJ&;l0vboJ>|bv#wRLrNB0E9Z>PKyDZ3H|3Idg6N$CfeHv6dEw zOFKQnudIJ+>L^iE^rV17&B)CSE(^gZ%qe%er>AGCe_+Ff*q9j8x^?fZKGe_HjLU0lsFjtK z8ly4!*_o^ai&Md+H!N$n&P|W#|Gl`SErd3{YUs?h%+}SxfBxh8!154J-GXAna literal 0 HcmV?d00001 diff --git a/docs/images/groups-icon.png b/docs/images/groups-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..25b79f3a7b5c6d3f45f1615a06ea2c0664a8188c GIT binary patch literal 1936 zcmV;B2XFX^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2PH{FK~zXf)s}fw zR7V=ct3gnMlL_FGK_faE!FVtj1%akpLque835#IF!)Q!qvM}U~8Z)9M69@^SxZnhk zBpO^W3e6@wt$I~O@H-Fk zJNsh-Kus@>%d~r|ak!CtsQj%3j0c1_;r(K4FM>xNR$s*&3BGQj4DGWxeafC&{Ws+r z`LiaB0YtZ8Zv{Ro$IcRXtjNIRi@4Y}0ibK3^+>7zyHXeLD~{`v-UukztzuQb z#P9%?Wx=ZJA8B`$VNV6#D}`?%Hs)eg7A({7QXR|qc!2B({ za^HF<%WF%zyJMoGeY{h@QVv$D86HX{pDzzksZ>x7hSqZdW%#fRe=CA#KAf^)n~7Ia zF(U!wJH*`_(8_;O4BQ`5;;~{V=(JURwt$>1Z)bUJPJh!md4ts@hfV1_z(77c zdU|?B02;MQE?2x?hIdQgR|N0taLeJ#UzUd1i7<-S=GUJ_+fKBsfy@SNe$vL^Jq26$ z7i`;|xAlW;AHPgbkF+yFCa`|LLQdrY)uE5|j+HObU-Y01H$8BGXc8mQ$ixv-bQPRiF#qo0)sS7`_C z`{Ql^?rcY^CvG^R$r=rdP&*5C`e!7I+%tSU(l)uKY;=&g+QzT5h+8}Rdy#$Ow($Ud zkyV4A*Ksc=!y*mlshFDt!9`rCJco`Qd^oqf(c+9|AsQ@DKM%FWsL{K7Rc}?Cr)w&8 zce9IkUiO2N+4(hw-`ed0Oe#^jN9u;>+OcaS$y7c{#gf|sHJCQNlpwv2T0WWPVfO}e)V+inBUDXBC7}SbNSBofwDz@&FE}nZ>oD`QNGJL= zR>de4LlXdo6!dqO2i378R%LKjPQF2L`8#M?3E4_CTB5-Wb*8A9f$HZ_DL@rrigo9n zbXt1J$^5+Iyt58}`F<6NFpF(Yftt@}JU~G^V21)qhe(Y4x!A{3Pu(L&I|GwL(J~*6 zi_x$Ub#qWN9n}V?)ZxpoCdDZxv!YyIj$31T&cP&h^`uiPj@MqG8~=&>cmOo=6AcOy z`Dp6t-l^YpPx-c6H~OJb%uUD)`Ax~^Zip&cyDlmSuST-&D@$@pWE>+liV{ydVNbra zUKq9I!9b5z&5j4K8dbksMZSKZA9H_7%>BvHos*+F^rPCz@$UVSeUQ<5>8jG)hij+q zwWK8Z1@ftgMA(vJw&aK%Ic!J5gd}JM`OIoiA=fBXV>$rT+p~K}M91XlAN3>Ksr3GP zTQ{Or=hzJr`Y=TDcNz$9{Y2G*yd-1ti9Ia&+|PiV4mtU7m-iJWWR{~dlmWEcHSXx+Qg&L z!!97FlZ4dh9H|q8)e6FD1c$0gXe9}52{^wSbp&OTv}O9*(y7{F18w1-xq=y7?rdCJ z0O=C)FI(~-F>g%^-zVnXd5OtCE!rM-4)i@9IZb!vb&|b>86qy~yUwVY3#n=@v-0i9E5A>=lzhYCY_}@2UKkv~=Aa?0*V?mM!V% zEB%qG|A~q^**i^Np+KN5e1R)4*5*&=@_B16dmfu<&Rnt7B-wIFLL}Rf09*309gSs- z-dl8|t9`J4V59^7zkb{|G|)dPr5Y%)ahxv}mJZ$US5YM|0I(r^=j{xYMOs`O8bg)`h-N&ZSWTgwKDJwN&GnO!E zmQ1RZCdrPs9(LyyzZ}(p6TT<3EWN{-5x_5Ja1V+!mrR)CrA+dxOyX-AiIpb7dPEXy z&8Xs+F)6Em{pIwGmmSA4*}hDs2P5_3mE}3HGTgXU{>AYtE literal 0 HcmV?d00001 diff --git a/docs/images/kernel_abstraction.png b/docs/images/kernel_abstraction.png new file mode 100644 index 0000000000000000000000000000000000000000..aae657c6f242a579d468a62afea3d00ad796818e GIT binary patch literal 25548 zcmY(q19Y5Q`#wCe)!1y4G`5|_Mq}Hylg3VC+iGmvw$s>l@=ecsPJjPzt(i4=_TF

    NJApl^YCoU|Y2 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 literal 0 HcmV?d00001 diff --git a/cub/docs/images/kogge_stone_reduction.png b/docs/images/kogge_stone_reduction.png similarity index 100% rename from cub/docs/images/kogge_stone_reduction.png rename to docs/images/kogge_stone_reduction.png diff --git a/docs/images/kogge_stone_scan.png b/docs/images/kogge_stone_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..437e5006ecf919fc8c590fe47b86d3c2f173550f GIT binary patch literal 18407 zcmcG$bySo8`#%l_7NLZIAPCYmT1kb0#AqZ&*XV(?j8*{wY1n9_MM?$?X%seCprllZz>1nfHEAYz|8yQs@0)q1BTPNmMf!}YuP=vY>5RiVm_(Pb; zO-cuRNb4@I@2>4^?e1mn3L{XpvvhTK1Acp;Zf$L62@6;kaUmd3&{L9=dH&L5J>B%3 z@uM!t$x88( z5(_3sjDr0Au2~G1Vv_5v7`fmWe+@BDvlmA1Z^IwGSNy~j`6jvCSV7i=<;sl@)wqhD z2AhSh^c|aZzmc;{nyXXzUgqE zVb=^y@msPwWencBp}xzB>+@Mp(XgS|U@C9t{6yw8gmDo#-VfTl6cPKaO~Ffh`E{Y@w}arPD?)q@ zw<})$q&*leng7H?myuL6kH(C_SZAhE%4zdIjN;~_4s<7zPt4a!4H}AzTyVD_m$O(8 zzBX1kRpmIwk4SqdUwY1d|1taBI){#&kqRE-JB%4iw!_EkstBwz%ENkUp9I!%ekY|; zx3>q@VlA{GH}VA8@Odh6Q6gNV+^AtTTnla88dNaJ7Z5Kx+5cSETCJ;exNba;da|)% zO4+((WCdEic@^aVi~KAhAcWcz4xw8xt*)yQ@JCEdP(LYoXa0SkRSr}cxiw-Uo z2p43+=`g&jBWq1VNaHgTzd5GSQz|_)Ixde`fVbALjZnX|R>^sMYN|2rn%rq7ch8Ue z(~n;0a|d+5%6?zg6H1>=H=RuF?2MUSnOcACs+Ewq20QC6{VAKeiJUalqOF!r7=Fsh z_bd-KhGA^1x=XxAx5esJ0B-(dorrNVtP(JgiV%HP2pehS*s~h@+$nai5@g@- zc0EENIcXx${K!n8Um)W4ftVM^c`>7~7WB0*KfX)9!N-B3)6lEMfFd#@bjBdwe%JFp z$VAj|3Jfjs{n58019FMfJr9D(7Wz`zq>J5`ZmL2Q*)*+B7HV%K>l$?5c#bIYnlc1A z(y3&VY=#ZkmMnm3ppSeU^2;7kPaEd+<;s&?Ku}~ zmM}J^=ie{?qKF*Prk!Q&(z2Auhw^YwG+%GbeqJ5?STw%~>5Lyx z>iyuiwRfJs%QQ<9|0L8r57m0@wZMP{kLS*zNkE$2Z~T|XPGkDzYR>#CqX8H-HyYnv zxjp+$mESa<%XITaX);OaX7yHJvwnW2Bm<#gB{P}PQ`L!y1D}2R=!w$dt%o*F17=1- zU6Sc0HIcX1KZ(ag+ZL@Dn=n@hy8ciR@XEGu(sXEEAFt5TEPU+4XT!{ z(B8AY^Wk(jtqkM0Y>%sDU5BeE@NVwsrA{BGh4#5l7??l5@p!rXhW0d#GcnEAd)A2{ zqA;SXMcU0ja@ZqxY9nptSSe3euGt7cosxtfy`+89wB#GK>qnznmTmNGaKfziumo@Q zT{OjeRzKlfEeMf1&^EIOW3z84`he5KC4I!O=;F09ozwR7x=FF3))l&wz`ro<>kx2N z@&wZjozbq+0yHPAdh(d#8{xt8r=uT~9pu8SwkNy7D4d?vVyYVwBWb_CyiL1Gw;>*l zbsgQZ;QM0c|4ek+SwP?u#z8FejlN1!JX6NyjhJzk5T@Z0Tm@m+wr>jbKxK(0D7p?- zKV^o_QFdKcTfFg^E4?ZU%?p)kU$9QQNrxPCAjwmykNi>z`bvpwW0`6crm}9Lsn0}g zhq6c(Z+x2T0Ow`84{ld|Hg!wQnR|(#s~h^Y>}Wmhp(wj7zZ+K&$B^%3&aXnS9K_`{ zV{LkRr!ISB<*8icNbUWc$U=LFMHNWo=$V75{cd)pKuOm-97U`< zw@qCm!%yd{1#BI@!qr%Yic3+%{p%#Yu{JY>efCY3`0F%SWB?~a?v#7yuhY4WBDfs# zzyCj&F4Jd2EXgg_z=Cpb%?N_DDr61h;a23ua88iFhlK8@ZxoJby9`)f6&RNSnelx9 z;U%TCA`mis9~;6ND`u50UWjpp%HZ;0Cb^bmuR#L&?0=meCrfjn`OS2-c%{Ei4mbdj zsfCLAUpJ_&7)aPcDW1+2|IZZyL4-uajo*^~^@{m1z=1j4#Z}qIF=P^fBlnczedW5Ffon2 z@5`fY*uh5KrmUpz`h-Xlk|v>+!Oup|u_KO0b%a-^;W0El-CQI1nBlGB8&#K7i#j6)K&oU-o2_T=Pj4KW&}8<+K=ee`R;%MubpD zo`f!fw$!xAiMJeSn#J0}=;r3;1cSBu{i4WxZ}NcfnD4exE8I#6dGFHTKnT;!wR;;m ziY*KwL@VSXSk|ko`+IpHKhE=QQ+@rnyormMfA03K{Xci}ytmIU>{hwU-(CjW&glZh)DR1b^>5#c z;&^hrlv9uTIgkhOesAHYn#$luZSpDvdlMQ5qaws`{+zcsRNLntE2oF5;i{c`7pWg0 zp`C9O=E(E@Fu@-DA0`M6z5vv;8XQVmmo;s*AtgS_E?o|@kM%5V|enO({pxn=UaFdzi}@|eQn7*^D=`K)P9Ycywbf{qeC z&H_OXT_JYVUh7oyQFGDaH(R>R-(I2+Mc)z1Y9+B41Ho}Xrk6s*0F^DR`F5P3ie`bR z;=hZwmZsUhGz9M7Ctwz1W{$(aH#!r!WkThTggduC2=;G(e{xnX5pd?K0ewF$E(+-T z7BjGws3K>z`4Zwi%qcM{oj$^;y^GN7>9{6do8u_02#cPX!Vw=0JMW(+LqCY#xX{G(TQ z{-ec_dVpTh?DH$??(FPraGM^5`y9=qbTUX!!{fWaNDj@iY2MwbXQIZPfJWuz6RI?j z{Na2lz;+ZE#`jU>n>-A)@kXhhw7o&K~J{db&K8%{AFV#suj6lmGt;S7ek2$rRTKXAsoMzRNwD?RY2!WEi#s26sf;6E8-uY@-6Y03%y#}ibXI2XS!dRR5A7^4az;8zI z0>n1@TNpw&)(%VGO^@tlq5j`e$aWvlWDRs0jlPxXqh$6Fr0oc=W_Cutfujm|=18ch z?)3#d9?Xjp8vm#^qH(`R&Ylp!ru%~>qTme#iJUlda9D0Z@n7*j>cMFAo zbZi<4(C3^MH>@v|Ut!LitaZF+f%A^IdMw}o`a(_j@4A+tW z6ZjO*7FKf_EO-Db_a&M&pUQ*4E-CX>4x^V``=_)_vY#(?SY_+$tsnqGchFjQxYG6@ zd0NIvX2P6WVj5RfIC00rc*J5`H)+}b=a;xj>*A^BRa~#VtU$8iu1dLZR{rFK^5Qv><93-of6f_nea~31@QtuB94(4yJb+Q4b0ke=d z8FFE(yo~{w6S2xQbhooBSzwSgOIimr5qS1~{*hF`l_08A;y!VINi$Z8$YpP_Uka}o}` zGY8Lf5c~W?8VPWv8Slk(-}t;y6QAx^9vPvOuOKMC`2b{Dbim2%#!lvWy`hnj@F169 zt?PU^Ru|?t;PWHs+IvLiQJ0PVqPDw0ZI84=gUfb$6&wz0HHhXZTBHgd0ya)|P1Sng zv}(S!WuCq{H=~{|4!fIlD59wnOi;o{j=q0897kIB=MuQu@9k${7PD=fb`5ue8A1y{wVuvGtmy*0XEpi;CRsT`QJ zIF4Et!^*RyTY zKA*!{08uV`HquSaoH!%YgD{33PmJnB^NdC?K}GeHGSP8@5O=zf#60Iz@=1O&r(I5V z<0{#WMf#8^umYM-PgkRT*?O@jeKpB&XB}OvJ+jz|9L}bmwZd*wyx)uAX;sSwq+f>w z{V(BXlL5kCZu&Msgl0UtX0y3?{W@7)sSF;91QU|+?B_^h-E@e#m2L)!0a=IE8h9l(&$xpH+W||i-CUCt zG7%Fnk6w}+#{6Y+(S0kiWFBp2?X`MA z>5KRFue#dEc<<_&`iaaG{Ve~^@Y?bBn;~$8+$yli{6lPq6`;(09+N%Xv#}JHL$3Qj z-Q?j2O=#Cc605hrX&1#;W|O1Hn-|Y$Q%x;uUZr zCc69&Dq_nBxCE^M4u#$Xgax?$eSlLT`^FTUtNYj(ssDI{t@rqAHewtEE;WkGki0G=vk1|Ka9X8Vx^z_d~C{3FFP<<~j~OA`e7g%C0a$mG8)`Wch_wM)JVv z=yNyw=E+M!t?UeMzNir}YcB6ejFGt2`7U62c&x^a-KvZT;5wi#0MkPPdDivwr}M{R zzs`LF(sA$C%HB3IZ%#Vm*{32vjY-!?-rgzy4xT%%gfO7-Xw z5wXkB$b!kcex*y_N@GAxC$1*TbKz2IZD>opTM$Pi5AI1BbXhUr^w0^JwqihhlV%Juac2=V-C2)Tn9_(zq}a z5kK?{Y=6jpD?G#TxBKprX7#5}1mz5Q?6c{vRH3e|8B583*kT`(cOT1KkbtA~G4K=< zH2Y*Z&dENf79z+AA?>Jrxs{D;3J54z9GQGK0!CBfV-Z$`oG!J(R)w>fa(ra8)AXqqPLznV5E#ZE*#Mf^wY*-nK6yK=$VMBQ_fj5aY!^rhm4CNyux44UYnv#BI%* zKaGzw`u>)29xXL)xQGR`mHM7L-TCZ)iU6f*48>RcsxzAX5PHF`V^TOB;CXQl=Z{BR z0CnU;t(%0!Gf&WmIG-$IH)de0%P5qIE7{o>*a6mJY0l<+c)e-YYy8}A`gA$~kv$vO zxjSjHMiV+gr8OdE6PX9Ne0Lz33?sc)c(DPXBEOW8@f}(j;xNE6wt@;230o*Ossp%v zVw&pK_A}2`Rn>O~2O~D>$c0WunmlHH`%D+A8FvvqTesp^O#`@J!47cen+XYrlrW@{ zVZh54*9Vw^(KTjhr}o3WzWIS3?&CD(tHiIb9S(oQ+s#*;RN+%iml@+YACW)Z5N9*} zzFEH$<#T>|Fm-Yw2`Fza;9_6iDGc4eKOl;(gj2;ff>FTAad~h~+g@I+=1;$LbFck; zR4u-2JLc>6<#cr>f#L1>;@QVj+T`q41g@h3VQH|<{cIcXtI#Cs3laOwv0>EU-Ra~8&>%@za_T|~%YVOajR~H;Fbb<(uqL6JI?1ZqhXYgaJ6ssfkoC9zwf)k8K3{(S&T2~&K>@T#qiBQzNTmz{#}&HT`3Ye26Vnn z))*>?@O2Ypex6r~WZp2sRb3) z^PWJN&1P5SZl{;Jpcnn!Z0rj%VC@*e!aoiRu&0=;y>`JR5v}odCTKQ}-@S&|Cqj6J z%5LDH<4vMqX(@ss4|9iXuyY@Gr0OXuFD3-aFZR0bzgV_L+enT5}jI$*9DZjeLR4-n#qELFPv}1 zE8x(PLx6-ylv#-dzjLcBi{t2twUxFC4^L zg~Fq`4}A|neog{qPPjq8T|a4@_yO6HRN;dW)SO`fduXM;sp22Wf=(o=q0>}=8*<`H zBlMU_lunvYgV$~t*A3>_vELAKc<`Ww%maK|(CWp{uUEDGHyiP#+#$>%Ldbw7-=pns zD_Ky$UN?eqAs0$+ANBW|*iw@)O8&8Xd)qastMeKs3>XI#c* zG}+cWN}WdZ7SbiL`UZjuGClsc(|=|b_pkWvS7eG*sV;E5i=Qr#-YfL|YJ-bPxYv~Z zcheND0rf#(+vzN8xewlG5a6hp7rUQb^rEhwQQZxEGvp2svRp<8~x1d7NX$S!Wj&vDvO=>Ke0W zme!e<5hD$wfcWtpCnz?s%`9iq#0xq#$Nb>Baio<9(zW|W#wa~0mcl?v)9F+_6vuH2 zV35|^A#k(wKu^G%atl!8iq53%Vqf&v@N1sBVGC(rOgA!M+eSQyF zo912^gSa=doFVS?5isRuiof(wh^Ey0Pv?CyzI`TE63%M!!+Sb!PB%y$Y0XsFsQZ`7 zwhvSCQyxL>l>CQQ=ke<8$2ME(C!D@uJ^)~V*T^8La*-I-e%FEA!Lfo4g;b)#(4m0| zQ#ES%z-(&3ZXCWeby9~M9uKxcE00L6qRXBiEagNm7z#WA;^GA?<-Ayo!Qgv6NAvVO z^qfR}*o>9KYF=KRXtmF|w8u%OL212NAjDhEyq`~$ZZ{%p#;~65-8E~$Qn@Z7e z^(QAjw2Zy?`h4q+YMDe*DTALSFc}y(5^0UZds8u4?(9x2+>=EPmk^lPM5 zct(#NU~g(+vsJhJ?Sj*7e{feI8@bgP&2y2xZd7&;|0v*h_JHqFW5*Roxt+0IH8he> zMaz3&k$Kp*&Yj5%sPNz-x8((a=;j&)Zsj653QAE|5l1ox<5x7;@s^G_Og8{(^_G;D z4tQl;X&(R(5m&1Qu>JTQ3$^Q)VlNSW%ZY9Zp$Dats6M9UKHo+)r8!?>{n7#;_Faq& zg{)+mwI<$=)6)a&;ilzVC z?#a>4k+}xCvP_?g`q$-dsTKpl0%mKJUMFI{+&j5|*-gA%OZ#T(qF4-!re)ihvzk-K z-D0Fpb2SUT!|V6VjRq(>y+Xl~(Dd3j-}3ZUN*~vpNCqQ$9#S?W8Dyu{nh1!3cvzPP zRh;&C8RZdZV%F-T#vy3_WPUu(74&`?to| z%bRak?KsXHlwg*WDJ{R>;5S{Hhccyq7WMAZ z2CZ?6%=G^3V9)GgAM41{6YTw&6D=(`uU+4D+hF@g;c8eU)aw&g)ZZ1lsk-Y;nvMDh zWI~l6*>U+}S{6>zS7d8hCl>h+H#hXBNnFW25yU_9?=$W|qZaV=P{Q#S5S0>{O&v6% zg(srK3dR^^;W$0|M0NQh;GeiZCfudf`Me7uz2a&I{ay)o=jrB}X&t!PG5R6&i-g)w z5|S$)kvSbVBLJ_J%p-oFT;rxrW)EieDuvDlsAZqD@aKwER+A`}+)}Zk2pw3KO?v*Hp)9 zIU*A|(W?b(XPk9`ol(h+C|w{l?TCYA#>zu!^^og%Pf@ZCnS9j?&lO8z7KfWklxu{{ zuFDwvsoN6XkO~)<13kyGn{f;#Q#Ra28ZU^wSpqz810*?5<7SmJc_$2YSK?cvhE%R@ zyU+v?u>;*Bmw}uSTH{-9>AQ`jKSHCNoN8;Aj_iYph+B7}>rAMT7M8=$^afWX(8UM! z&QeRA{PR-5^B}N=_(MD89&fh8)EJtgkODo%5>QJfLu*_kZpL-YtfX!cs5;F*Ca7a(Sn9BG7e| z`;C@Fi8!j_EQe9W#kBh{*+e>D*E2HVKFfTq=X%Ofi>_Tq>~wjlOJ77Qy8hZ12&iGs zB;a(<7vfxFv9|aW0FQ)WNLkK#pg=^Kn;Ng#9K-jXk|&-w1@L8w&fGkx`gX>ElP!)N z`c8vr>0{ecY6xVTAM-=PNrXiPzm;6LjCXjjOtuYp6XZ%rpF z1xo~IRA1swIFdf_p`IgeKTR-0c;1o~m_iKeNTuT6_ICHK(husK>bE@W_k#aehOxv~ z?m$`?69sDEk=c-YJH!=`_|Ow7w@MOF)6?6lu>M5}$gG!#tt#1`0q#e)=%;qVMKN8h zuJiekt9<%r;El#kO(1Fw2kFsT$35%^Ds($P!vUz1w^K4S0l=#;kq<8Xfg`7?wUZ%H zMOj0}*+h4$)4>;iFSmEAzqYPcyM2$MffjAcWhg}rkb^ihEjTeC5NOdq{z*l5z3U8>!n^3Y&31C_#a#MaBeG(+gM+s0iq4=E ze6QJ{SE4B zq8Sj589eJ;Zk;^+d!*e1rIhcS)zVt{8yjg;+35f&K`M3L9fCk03%zfFRseM}2nSEQ-C|+-N#K>qHh7`Tfc9#zCUS*c-JBhY1wi_{uW>TS$YF_wMTtEmE~#kb#b%4(Q{q->i74Eo0{CIRZ=Ufn8&*IhYA}Vmfg!>DF80HRCr*Pp$=FkcKsE zONMT97664b(E~c@1hZ<5Q8xBwN*-LPd9f{!uvb#4bz7i{O#1N0gaA(9UCChh9vVEs zRu6zU-lQ{!ZI3RR7k1un?k*1s7+tFZFec--JSf|lEF7g_FM->wW#o?-x$9NJp)4zk zlXYI8C**pyW9YJR6HlbP`WbJVjx8)vdNiVtwKuvFPKjvc4EidFo32B_NvT@k-WgVQ zp`sp0MSLGzS@Y&&7D8fw4iV`qRypkBl8U7~FJ8=?pB<#98Qz)wkt@3jfZ{bKD!d(x zb~ujRaEcr968roVfUzF`W2~z=J@XzosnN&1#iD9#uB=3zM7q3)BR~nU+zu5Ey9?kC z8CQH<^`YKLoFjc?f8dA-kx&4{!BI*m?*mBWC!0=shwBd>QOeqf)o`wMps^R2BpJO` zMoa8Ng^>lZc5;!`2%hz~`Ca73n|(a%%0U2X_|P`3<+d!mc7fma`U)aGV*8=#i*^%5sCor`_xD&;|A!F9xCUPa^}$5f8aWh|Fr+EYEHg!lIOGd; z#Wwqc9eS(7r)r5OThRe&y>4UG&Y6bB#(TZR^Q3^kQtm`7&D#RF+I=nSuu?Buz=S>E z0Wcx+$(JaBf299Q0wDcj_kif9J^`A&dOs!4nDciRXYSxDFgerEW0s#_)ettTx3VEz zR_(I2XTo}hUXD5pioE^m(6V~^ZW}T9+nM$OjH=RKNy&#-DpFL2asU;y-BU?fy3RiK zB)JC1&)F#X-wlr2#+yJiUIiSw&azznjJP4jVEY~Cs@leW91#56T=P#z+bB#n&+#icf~jhbR(pg3_szz+e(RZk@k^DaSXk3H!=a!d zX!bgIbgK_jw%r)R|N4Sbj^F9PnGf<9NN7O;^ND(*yF3X#v~!yS_ibH(b-cAlAmgHy z7jSS?!G=VHXG{@`{a28fi)LepMOy7+p0FYE_2;{}i%%Qhr<7g}g?0 z)+NyHJsD#FAM(i+MQpOkfQGzOF*k&^3=J(;w66*C@V=%55b9}9&f`+sCLZ`s zp^%OpEkDQQke^m)3iBgY7BKZTGpK1yBx*!OmXf!l>AEh<%h(n@->PpRF2k!|wKmc- zGiUnf9)j+RtpPZ=RI21;s~3>H_&&OU$ZFiFDsiwxp-nn5VKdqoGPofM@hy-E=#_dU zJ$WnZsCKBnxu`NXCXvowDQ7u2iBifGDX8KOptUE5YmUrTjl31T)E}cw^mt8YR8um@ zAhfP^FMi5?n(?J;D&_eOjpp%d7))chkVj(5J8k< z=I5`jov?CSre~wpkx2*7 z6n|TIXYGA#w3?q!fO9s8N?O^?d;;2;)TleqE1dl#LRvt}wSQKADbSSXOk&+kKuQxb zpBrdY>)v7IFPpkEf0f;|bpUpr!+6TE85_g!c3UGv{n6RyWu;G_;5bpQ!{0wAF??=P z6OP>X_>R@UAEijp48QXRH^?$6mrzEX2wR-*N!n=Y7tb#y2gY^YgX_{S$5t6Kzx@TF z4ks;A?k-ny@y-Z1G0ukWS;?AsbAa0hItk@QP2Oq(HI;D27zF2$)6iaX0cmjVeUDV~ z?XC%*7>vN!Ac9p5pnzpxOP^?HmQ&-?cRJ+c{FI=EpC)e=82yCF*d|0FTo2(6Du0T4 zgaGzxS2(Jx*2hzlY8dIKo1$1UWctGv-`BXq>qbn&_Q33etNjwnQ89@AEG`jccBhy! z{_$#$L(&x~7A#-G?f7QF%HlU;A=b;d&&OAKjJFvYA0@z+gfu`2lMDDh9>2^q!j?Bg z#4XV!r*TyrG21Xs5K;0&jWrS`H^xpW26@mo7NDwf>?@|u41q(-Kaq3~6qHw?)pNpz zWCMZ}?%at#chd)KW z=!EF@{76bq?>;x#m8EoJlC2&rMNOL*(Z|b{# zv^LylW!lgEz>Udi^0T??2WqXdZZAcoJV4jR}+Mxfx};I%R?N*DcHC zRz0?iuLJltn&D7%Zhn`Er%+Fwpo5~2>X#c4F)>X&R&{uE^tV#FJm`)5)ejN|^@sL+ z&IOS}6@9WmO~cO5=8M)%L7+aUWvE%AujTw(Cw;vQhtZ2d>KKYwZcb#_93Bu~xOKdzmPRY#deH}cus7q;z1S$(qiIEA{ zOFusKXR~uZo%_LGu3D=92W4i#W>Yik%!K(Zp-A_ht7dcENy%HuQVyfx=QsP!D`c{a zrFyVGer>)@tL`WcB>)b?0^vPSQCb^A&sT6L%W{CdT>$8s@s=+CxKPkP6t8CZc6>y zN3Z9+FXFwsSC18X@3)9ACZ>62MA&!LYGBv5$*OKb&lh?ZFDrciU`nUxgf*fMT(R4q zDvX?6lemSH29d8E_1UXMSTEz}{^15~*{%TB(?L{)3Zl~J((vwp&qb$YXJ_XG3k1Y3 z5_VBhRc*K}plkIWKr2^#sb9mi$D=gA7wC|64^($s{CjkT=Yg(Zzul$&lNj#gcny=P z9}?8r9qrj!(?C=euPqkp!&FQ*0rc5H?;?N>*_dHrMdUoe4NcuXo(S<*A76vubq>(l%q=tf=x!Zd?I6mb%#-TSIBj~`#EfvK!mse^OJA#)`Gcsb8d($ zBgZ0)gL_^)bl(`YUDDw793H-ZRGSOHZWqM45INwIOE)zNMnyCDq{z494r)>yxgQN} zAN>04?7bY!@KciSLNpqb4ve+MWGZ$G)h8-v2l8z*N7;c|TBc2W<$qh|N6w>@JyxNg z5hjG)kST>C-spQK-Rnl&KD6NVP z0qU`icvrP?FQB`@ZM4j^m;KDZ*mg!l>L9n8bJi-=`N)jyGSG^LeW!Ok#C7nS>(Vk| z3>D1?1^un|dC)k}2eeU)6UZ@tP_(~pFSJe9{FiuwVX&p%Qjz&$&4Rc$OgC0>-_-UYBiv%(75`~H}NL$s| z$Nfe*ssLG@YtpM;}6&M!Qh9rDv}6|^GOUv1`U_-Jzd z#)H}nVgo(33)YtJwgt@tf_{ZU(3wpa8rB*|*wQxg>Owr$@eetGKGX+}iI41{q|t=f z^H9ehIl~o??`RgWnq9nn7ctujw9G(<+!<$}OGgV|{@oa`5Q+d!hXSQzc;B-oeVAC| z9BRZ++>uxJ{LW*VWe|4_@JNDk&RY6Fqf=RkYs}|}P1#-F&Hq?j1wDcbDnObw=J~r( zYXwhE?J5#)!3&@UWduO02Nbj1-QAshRPs^J?9fW%xTi?TQRSVJwl5Ia{1t453;9&! zT@5rJ3)3-0Z_l5tRrHFl@)i^|^1yrz5n>kU9RicL?q~zW9DAyu;tbA;$_c)-#-feL z9eYYT@*EuH%%b&w%;=x=fXeBc19j&B$$5W#OYGM|Ms{`v388n|L~`(g5dX*BWXUsF#S@`W$-&- z^`L{Y6mz4dY31uLlr!XQ>#aJ_rDJa2dq6tzbzq+VAuU@H;7d)dT3L-3QGCV|!kp;I z52Tx5rUTn3JcHMT#+wY2M(r9043s)cy`8XqM3QVZ#VBREppKlrw%elh> zjIso|Mt{kW@|gsBY<5cWH>c`Qy+535t(HxeSfwZnSAZeSLkSqZ4--6+nUAO8|MtF9 z5}2U5ccVS+bv{Ih{^#q*7c-a?j0KL2fD;hcPDFyqsh-CecPsJ=BmzT`UB{#T}l_j9=}ZPOSU|*q*zT$=7bg1U@2!YOzb*5UiFd)id#CHNDSN z2Wk8KPtJMkPtFOM`UOC`QdW9GS`d{y6VwWN%jBPST&RqFxoSU>z!(U=+|{cx!lnLy zpZWRC+P3?52#P-#m=RLR8nhGqJ4AFyZr1z*@^1O>jFQ<+U`8lOwqVfe?-0>%U>5fa zie~Wdj8Zct@H~I8T0zI(1%E&S3ID%_ox5K@8Ss|z^%9-u|L zSJZUwbMVCfH}%I#rm(XXil%k{or+AIspGf8fk;tcRf$di0+`W|Au-AuMxw+#pl$8|q(M&CJQ`zu8;} zH6giTaC3+laXh&&zrJGLVL$1gcY>6dKG_Y-e!fORe3vcHc1!FZI%_d&)F@jRy(S{M z#YrVKA^YcM{7P5sQ94nEea&X(ap6>%iGRkn9*A6u#Ph#{0G~2dSt$7YGcnB;`E<2S zHHY+G+>N_PvRa@wVmE-4kF2u;Es=DNlhHeY=nxu6KlU|s@p+lCa8(3`w>5;hnAhx< zVXgQ0<^?%pv@p)E;0`1--@I~eUaWHE*Wa1v_8E1a+KQs0jkQVKMq$xW(;H)fZDOCe z%JqmZV$U*|8Y8yofe*@g=MmJeUEWD9S9f2rco7wAlejs@b7Ork;C#VpGdAE{WiyC< zA^ZGo)KZ>jNm_DZg#N#^3P$=#^koiwRIV7`!hN!wz5b#G+v zBx#w~Ks^joqQ^z{3!EwV(}8galPJ_Mo^4cm>ivFEbIz|D7-p7hXi0>8m=Pp{JE{M| z2;@|knGRW03e8%is!Qaom~&hrd9DuDlDY-foERySo<+9_Mo?$Cm`)j-!9*nm+^{g2 zH(2F@I*~z170t#9>0aZFm(H!}9ajaYhZ>6=oHHd7_a=AK+=tTiC0BJHrrfCF1@QWH z3RZ`Uspk3C5seSxcd{3<(=yN@v4d|+ug*D%*<~vLJq0%mJ zDlYyrylZJaKAff?o%R+^5=UDWC=>3x_MU0p%p4qFzKg`0*W7{n z!)8Qwy~xO@PGwUVLwU3qdz%FE)}2fpw}bhB*y=vnS4>xa9ZqlC?8CWR>wJD&BLSvl zdTIkb{U*qmysxKLXyzR)U&4E)HT+LQ2SUyByiao*ayMy4crK4o)h&rEJWyYEl{P@NBKchvf)CKP7rh$Q@o`Oa{pE&qQ&;@PX*jq3?4H-0$pYZ~DzJ zV{P^13+L2msy#ae>ltwL++H0$3#G^SSG49hY-=q=vTaa0)zf;-amUf-)uj*`8Suw1 zvir4O-aIcX*c?tOl%n*|ZQDoSqq*;_-b_}6-yStQxo}^O4mTSdwQ<=v1=L1)kmu0zDnw>+!I{aq3AU@9f#PNy#`}VlY+w zJf=33LF@;q_kkQO<=g9+5~;*4T$to|dE!%H{IO4QS6cgmO&UU4mP|PU*1u-Y8m>f8 z;e2JCxC;~LnJ;olkL~)homuazZgi&sHQb<4l+@Ji6qa#Uif}$p&7nc4bK5?H=Y^7^ zTXdJ1Qt_QKv(yqeo#b0zKf{FAW_2Ut1z(Xuqst2oH_=A!Lv2ue$ww(#7~Shn&bCUd z#p#6O3l+Iqo%p*)(K?EUdS2%v>t`+C4aT#rOoIxmURiEtw!h!_5LC|8=dGCS80Pu% z)t9ehhnZymn9HY^xGv=rzUIJO1#Ihce{<%)Mw*8E(gGn^`@)JA`}T%1{T-ea3F06G z>j0n1tW&W4W3e9ul|Q`AYsPVn>mGMR($XLvGH2sLl zv)Ah%%XKvE#1xv`J(knF9KvjSI5TtF^YZGgZ8L$W%aO4K(PyZ>etM?m`HXh zCz>?B2{!eebdpe!UI#u<6fxNbSlIx9q0 z!W-@`8frYe6yje~^ou6PQCT2!-TCpH_6U2v5pvb_8yxdR8e6YhzULFV-M`T5@(H9X zAw-Ia%ucu4@m@aY4`nI#k;|SBeQYuG>-wq&0Rdichv@rVY;0>5*}WHx&6qRo4$<<6 zjk^P)vGQZ6^px7o;I*XO%X$^jZ)aBvl!!jJtloVCKe|k!7CLpT;rX_H-dsau&e1W> z=$W-%l0O!7|i5*P->(6_9iVKJVq?9^Bp75I*lXl9#-x>3OnUGXT?hUs1Z|M4f3K)0S+WLP} lc?&ByI)F`G%H;pq=O2_cp8`NDf^xGy+PF)X*(mA}t^T3P^WJ$H0KJFoc9iNq2+5P|^+3-67rF zgMPoie?0f|ynS8}=kqydt#!`cYwzn?*V>_KDzdm(Pp}?5cz`P}C;jTd0~9^v|792` z$loNTr=G|^4;^30NvjE20%w3E|yeDDC!cK`FR(>B-i z!2^L4d1;B)Zic&GaGf;Ur}lMw6iQ`EbcQ}CTVobg=llL@-TIJ0`t7u`@>Hv$`m?1) z`ZB06H2;Q9s|Pzz1~VgmM`8av_+0_$Yz2_=KWgo3t8TXRFS9 zUUc{O3z+STc=q>-nx);OIFqtsUJ0A6i46!hyT5-wKz(5A5smWg!838JD3ny~x4!En zv=8MTzVaoeMU(UMAp&$`{(JSXmG0v2eaPDnY+LCB9{zdi{$Vg94f6iKkEK5-q>7=8 z`qyZn)Zstokblbl`vsF?_v8N}&Z(JN!S=>=e_$X1 zxiI7{nRcmA=-x#^PI=q-G1PmwpAFRINURILE}<9?ex~`&1@OW&wk0ILUQeZX&HicWgRx~fUycbo z?iQI?EvyUct=^eoGT-}8?A9&`eRE0`S;~c>6*_8gu*QYmEq}-!oI*~q0ji4}|aZiNWn{&a2 zXE4Q%rGpRG*`=h7w)GQF+RLEBBNxhgl%_^=Nw>mh{>;V7ai4`29Hs&r*DvyI;t;3K z?n0kWLrrz%;A=&ogcj<75)HK;$r&hhGQ6=5!iWjTvi*IhavX!@0Os8pOnF%W_ zeuYX~CArYoqwj*Vg(%E2N9WozhFBCFb3`%pWJ5&T+55^AFED#71`}NDJM96~+XX}|-7uDJ|vG`fs zA$-$Sq^zjkj+5j{f5lfQ6z!FaQxyEkbUM9{+BATjqhYijTw%qQYGY-A*g(mLn@n&C zQoEX0nCNHErrPK3d_Pm6kX=WeX*;J-6-nw08iQvY#WS=-4vvPsMt@4s|GvY71{Z!!6J6>NvEs4I-J99Z zC-x|l9;tJ)H0cY|(6Cq?l}td8#+d(%yeVUEYbfaEE;J{+idFzB9Mj&J6VzEW!bS2s zTu38Og$Ne8%-_-hlMwo;tIqv)h0O)FqACiKBh|%{{UvkSqoPjT&mebOioiFM^BRz` zw|Zk)V{b&uFOy_b<6eB39casf^OZakE!(mkTw|>DBReU7mPdq!OO|mSC()jDQLl*? zws6M`d}+6=HuO*arM&XB+lU)J7Wro-ASigS$mLH7g}wZnkPC4rfl@hf+52>VvpnQ2 z8U~bL2K<`m?@IA7hnN;9n8o9T_jgGUf5f^#0-SRk5b-+OmbDAZ2Z0LiS~tLme`!5yw{TA{^O-Ytkj^ zt&6fW=ndf7O&Iy29i6H(^+iQRm6etG`P%__qHm*T89&yv7WQGgH!Yh^Jl5U~?h;RCWa5c? znmxOQ(O_6-roe9=%0W01Psy^irT`~uc_{*uva^{w0py4fY3!kN-0I=j6b)fbURR50 zA|Ka!6HiZ1^RbpaYMfGSH#a7)r2l1>5DH1n3lt!*8r26&r&I9TypeHEB*31U=kz-8Hf;H|-1kXY zS(%LEjW{Egg7jYpky7;rL7FLuV@m*OOFLpz>0-DgvRLI}HPdPi#da-L*(?GwNAK;@ zz-MdBqfoBY@Xa&YSE5HU243}gwI##X>?K!i9C4pM_~Yhk0={{#Ztl%~rK;d}JZ%~= zZ=kev1UcC9i88oiOjD;_UWoyS6@sa;-+br2+VrzX6=$72Y5EDx`Or7d{d(8+{x4*l zhNhVn>9H5XBFMSq4UB;czgaSK0Y=bMkH3Q^9N1=%Rqw!O zsuxUog9g{4aye3FzQiwwi~Gl-5|OXqstO+4M%dbF__GdK6=}Jol6}t;&Di z*C6f9A|C&*&&^(!-D$T=w=-Y)t9BLVG!ioKL|hC8Uu<9?Fcgzff+}{NBYj!q37fUz zf?W6KL_B&~3UrRH%(kFGXgplcOWp;7PD=DsCi2O|}!z3Bo3@=84}D{21d zfKt~EQtZWiGtSDH>s8}o_N$(F5&3tO`I-azA@0$&3J|_Nkyu3BcH*BbYxHju+G}X@ zk+P5n3P$dqyp;@SQ6>wIPKIf7D!S9L`VbHzV3$hl62#jB&mn;bUE)+{X~Ge$LC}2j zf?}l@?xbiNNG#YPmYS>TLP_iQ}m9vTR&_GJf>EF9Icwr!q%afM)P{ z*ssP@J$fA;$5#-?gL=G^?xoYihNtpAUd;QN;fRx?ECLdS@Hz>WAVku~K?7^X?Ai2y z?N11xyDQtPM(crppvGbEdh*7U^9_1TY3O7DT(PwKbgz? z{JPlZW;>X32H&^sngVqRrgS7p`pvhk-L_9j|4zZU7HX&C1(8}GJ43Y(`Eqmb$Apn- zrSW$MCEl3!McjR{+*RxNTH$Uyaw2oKpo5oLY-Bu@l!%D0$*~~NU{79 zySo^mlY*YB#`7^NrA|3UI!YaW+p`#ZeYW-)L=S&N;HL45xrRn-`!%thO<|{p=qghw6ZZZ&nlgiuE+-Y z9ht-k`q~+RbusJ0LFfPib-<|B6B`=dj>Q?Y-}7JW23iBnN^6~t_DE{3)TYbv=|GZu zbHE-Ie+(OrY)pWBuQ+hdWBP#hi1Y?uCmGD$Wy1+%`Q4Q%cBv!Cb1fv$5_QY@C3mGMlHj$AQEM0)P=D{A+5&y+aH%4j*8EPArH!}@RS zZiNY&175Q+0D1s@?K{I+v)=x(a6j<%b^3tORYluMgjA-pbgxTz(^+y)%=)|L`j2Ls z{TU|u6+|Dt?!SJbGEhNGB*@R$iDr||0K$YmNM>eIEd7j505p?K6`nx&HQ1><{7=iOEyA|T{ zrhcQjw!-y8g{!7em+9tBtT&hSuZolu;EY>Dtn+7&Y^Ul9=l6N+13U!f=Glv%G#Qx| z2U)?#V~#%_Ai_Fne5@>%D6gg2SbjBp82i4nvtvD7H8wh$BH~H9&SVK?5~5+SivDcS z8!FWwk~xK(htra6bj@%pE09miHFN4UNwfaa&x&x(($Z3Sd3no;B6dzrZ4oucznhVP zI=}0@(p&SVr_wH6b|E>hfMC0~T~Tzmo*(?JUrlPN3x7Dy%~DJ#(k;&}DJl8>eQTvV zHi5%nYikQ83Ot0`;zAj-2>@saVb{Hx5CVp|*|OBMkStGEcEbj@ldZ92e%oNjR8g-d zs`*;{wgeo=ts+Hj1-T)?Gg{ic(oXRK1Z+_wR+A-*r_;8ox{bq($Gxd{FRF5t(?qF8 zzPY=*lY7w!x!^>O{`TyRJp%cc+iq}{?=ZUvVfKJ|LHn1N1{AfMj7+8yk_=2t*+B71 z{or{*H&jS^3Ale(NAU)^^^S~;ET+JpS(}@KeQvKSEhk2CM^jv#kqefY_GsVi#jRuF&~?Xl6J;(SLx0Gk!91XVBzH@!RDT>wk<9!w6?Uw{)ka> z1Zvg7TTEoLZq%VUHuOB=lx*h(Au)(F==a;_!#m8p9C-3)}MeW2IoaP$b$#YlN*7hb# zQ776GQNL(-WGW)TmlViaUI{eo?~Mhi!!ytLJjqJ({)R#TH#hjeZ!q9uAmA|`q$n>v z{lOK%ix)3^fAsb$so9NWD?c#S)ty>wgC-{@Pft&uaI0?(X3@XQ#WrQkjvH)yWxW=! zgHn*6uiy0X0ud@^idvbIdTY>r>wq(wdU3?9k)zT+M^Ql5YEW8@?JiK{`aV6oKkS=% z?tTnoHk&*qG^3Q)U##%NY+RpZwed%Mmv>6an7fqmOG52nqo z<8d&NGqfNi6W4bkp4`FD8XgZ_Zb6N{ww|d0v9e;L@-~z-QV=5`#@^ndYjXMd`BQTo zX6PR{TIncHV&EC|EJzIQN2)h;d_&QQHlne?5R-p&K+&PA4n%dlH|!7@MQ=#h+j6_3OB}xVP!S>QC@PHnFbJz6BQ3bMink z>et8_pXU{WLn-P?0^0_W2se$I#~fduA@2N@G0^~jl#V1k#%8dGPlPqwjJ2qBdX}DP zPd;oRr0APDwVu%Rd#m1{TTX?PP|AVtx$Ih>VOQ%E4SVNzmH3e| zu9swB4Y_Q(>0jg-kM)o1;;fEv*|EWyo%5i!YlQESb<4rMB~RwB3si$ z9p1;5?t>e{Fl;W`0|q~5JatvF&^$&`*%I|6w$%ajo8q`R)z^mMNQ{w&ahjX9#<}3QN!73DP!xM; zJ4V6Ja7zCEyUl}#k-!$vxI3C9nOc4N zTGwKxY$W6@*=r>zE49KS{%$~fNY@s}{g7Eiv~4iZFLJ#GD(o;15x4B3+mkXFdR#m$ zaIi=JZJFlunx?3O0E-qf7#r}dlWG%Pz@CM6Z3C3aWxnv5FyYHK_)}*hMd+qo`{yM! zaV6j?%O9(uZ7laz8G%^GvEz!&@B6O2By^Yd+V)>l_s#hTC*bN$U9FG2-1fn}G22A9 zCW-N}!2+SEJ_)_hQ(EADsRX%V5R{`ra*CMxRf)9+-*&k58$X0s?Ork8{v5YF(bqpox!M4ItfB(-K4TQKcSDM`~*`~QP?s5=*MPRAR%Zla^<&AjUU z=|v)Ua{YM)W1d`p=5}m4rhI*sgp*wW{ynWOBoKD=$i99R34y>!KwZ$B`qbV|dw#nm zFxWT9TG^dJWS8`nOuK;f;WC$Ch#Z)>GvnBs9v{d)D=2xH`fi58d;5TvZ3Sbg2G^w5 zYhI~8vAUGecp}3oOJaru64Btfl5zRn8*&(A`*9`IBC@gegH}g&P*>GiQ$pS+cKUBi z&l_fkx$P0T&8cb5q|e3daq54#!j=cWrtvT{#*Z>ForTk%fSq3K zNlVUiM}p-j2%Lg(s33$0&yIx_e?XPM8?gfqGk>?0FwCbyf7+S*Ebh{80K~mM_QFbg{ zk{@xVGAzXMls`sUi(;3p?3vDBdd`=JgK_R@43_RC8kGUQ85pOok_!LkCsj4an_DXd zn|)%VeJYgUZI0RWSqz(JOovv$imIK$=EqZSel?D3@|1h(6*Jnr487xvqEQ0gbuGs> z1V|}@783`FA|~v2zecATq@k(e(p5&M8lTZqlm2QqCN4pS6Cw3+_GD3S|N=N9tJ=a4y(i@Hi&yE4y|b1mvxam+S&qV0)}+Q4J))5>}=N>(Y*RyY}Q z@F^h8?NGa=eP=3trFr~weDrmt?ML3*%FX_Q)?eSjX6IG!Vr7+Zp+{uB{G%gpr9OqG zE}qcqLmb{ihgu}>mt^8C=6r~WNo-8ac#(m=p`rH@0#i6eLMTx0@}bHw?qM2h2ZcQk zFtvH~eV|nAv!+nIYrE5(DP3LNr%#`L`t-@|gK+91**mj%`oJj?M??t0zKyP}JF~Bg z#O9nq7#U}W2?4+D+#5|z=gVV@8~ZtcXY`iTuk&`(xrnyDr}v5G4zLJ&LP`jbYR{PQ zCR8?y{{;hEDPXP3rXlGMO^f|I&xzX6iqVRSij(b${i$+hy-rdTi2sLboaUzo!L{P< z_Sci8@t2=jwX<__)>l^-XIg@TgOAn+7jDmJ7_(-3>U&Bxz18^u_AbeDnOI8yNNZK=BMz%_kj~D1_=;(x8G{!Qk zmL(3Gw`P>U7btSI^!4?%467_{F&R&UD5+3XJ}%rwGnkYxJ<>za^St0*)2kWeyQiAGgdCEps;YjhkN*Kb&-GHKO!bvo_*epR$mw@q9#-2gzuXb{x#4XbjKtM% z>BYoo9KVf?jj=V3b5eYW9+e>>i@1GBW9p2ACSeGivu7X`AFIBt|Ueq6AK5G;Vf<8PN z(V3Znm1IJ6k!otF?E_(?zT;2YaI+$WF z!HILi*Za5SPffY?E?zirOuGUqzF=%Z2LM@yo^bP;57O51{hq|FMK|vIQ(GurcN@9bRGZa`L}1MXVUm@xB>9TfOC#Ea5D zwUmCrOQablEAU40M<<%$BqT-Y&8E+2S)t}Qm`2T0#r`&7P$%&iG5W~(yClbMkkRkf z`O3zcwQVy(4Gv~jYDnp)Ck8sIWbW!UzgLdWhyd+E*fYN{tlk&# z2T^k2t<>8sqTq-4fC{0_Z{J7y4Kl_l-b3Pu&}VzAJi5OcKfhe+kuhB1iD$i+l4TOI zPzoDift#Daw#a_hl%30k@8VE|Bx3bM}py!j~Lme7VeE=R*Vll=$L=y z=gbTWGMJTfDKy~Gu1N8Cm;JSa`+_PaXGux**4>Ia*+nsT$_Yo-fX3+D=kB^W!t2Wr z838~{(79<%u1Cv{Yw-bK2o(R91^8>oz+BcWRRw(LZZ9&VplpU^I>`b&FbNwx!PY_| zayxk?V^Dy{P?OiyE%6z1_;80RxlhK;^=kf?gyJ_H-KAF4LR*hNIJA%Ajdny(Z4(`R zV77_D+|Qi=i5fJxT%TXnx80);JSg~wyl=>N`*Wn^;&QWGHnhn09|

    *=JeKjma) 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

    OM@*<y) zkRI>qG|8SLfTYM}5c=}vui`IB60&@cUnbb7eKGsl8m_;i=CZN0GkCwA>w=JzL|fjO zK=`mn9vrSCSceCNysGO$Q@$)0tzG%+DjdK`IEW}G(e|?@3w=gvHGB1}HACEP<09n9 zrf@MT7HQ}AIPR(Zy8fGj>*1bfv*}p9HSO792q(@-gn|l~7#qB(D-Qv$m?0x?aK?lR z-p`-asv0arotzRVx8_U(X<=`bQk+2pTh{u37KOw#|F`qtvlCbE&k+4z=-RbWwVX3Su5 z{O?RXeZGLDtqlUG8IQ<7U=r<(Y4kvttfF=eFEUm?OlY8#o{$sg%ud1#E4X1ZJNW^6 zZSi(-vmr9wV{MM=wu@p7vD#1u-fzL_dy|I7K4c16JY|Wt53;ikg_ux{x4)Pk}*Dd__T#_#(@|;p##^>Dd f|DPT|zf0VAo~V&;Xhoh1eIPHRB3&f;*8l$iz(&zY literal 0 HcmV?d00001 diff --git a/docs/images/reduce_logo.png b/docs/images/reduce_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7c211160f779b59101ae48362011514721d7e187 GIT binary patch literal 10611 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 literal 0 HcmV?d00001 diff --git a/docs/images/scan_logo.png b/docs/images/scan_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c2ab25624507a7d10c29c295fe4347f3a872eb GIT binary patch literal 8452 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 Umu`W;KNoP66*S~aWzB>B54_W0i2wiq literal 0 HcmV?d00001 diff --git a/docs/images/simt_abstraction.png b/docs/images/simt_abstraction.png new file mode 100644 index 0000000000000000000000000000000000000000..bf6aa33fa4e5bf9e7ea6d2a78c054e6e826fd78a GIT binary patch literal 36651 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 literal 0 HcmV?d00001 diff --git a/cub/docs/images/sorting_logo.jpg b/docs/images/sorting_logo.jpg similarity index 100% rename from cub/docs/images/sorting_logo.jpg rename to docs/images/sorting_logo.jpg diff --git a/docs/images/sorting_logo.png b/docs/images/sorting_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..42b7d097f681915fce04763893bae7dafa105e27 GIT binary patch literal 6690 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 F{2wjQ$oc>P literal 0 HcmV?d00001 diff --git a/docs/images/tab_b_alt.png b/docs/images/tab_b_alt.png new file mode 100644 index 0000000000000000000000000000000000000000..e3e58fbaaf30269b1687349e5298676d6440dfc4 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{M!3HGXPAxeO5-1LGcVbv~PUa<$!;&U>c zv7h@-A}f&3S>O>_%)r2R1cVuZ15jAD8pe<8lVb4^nbJFrEUJk!_9c0;omN0m_`njxgN@xNA8`3=Q literal 0 HcmV?d00001 diff --git a/cub/docs/images/thread_data_1.png b/docs/images/thread_data_1.png similarity index 100% rename from cub/docs/images/thread_data_1.png rename to docs/images/thread_data_1.png diff --git a/docs/images/tile.png b/docs/images/tile.png new file mode 100644 index 0000000000000000000000000000000000000000..f8dc435017934d22c5fec4cfe2a17de2d9c562e8 GIT binary patch literal 454 zcmeAS@N?(olHy`uVBq!ia0y~yVB`g|O*oiJ>Ao-g)QKCAWU9`cYs}vo|jF z$~BXJoImcCSjDctp8DrP>2t-?P-Cx|JLn~TMsmQrjOOUviGqQUa}a?bwF{6k2+NZuYIjO z_O`5g_uW$s^*^fS%vz?ocv~EQ{_V2OH>Z4TUccYz*iMN4n28N#|#+u N44$rjF6*2UngEmu!H@s| literal 0 HcmV?d00001 diff --git a/docs/images/transpose_logo.png b/docs/images/transpose_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6488068d71447eaa027027268e9c7caf5a4ea8bd GIT binary patch literal 10786 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 literal 0 HcmV?d00001 diff --git a/docs/images/warp_scan_logo.png b/docs/images/warp_scan_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8799fb21c1fd5a7058aef20a6f0782ede235b9c0 GIT binary patch literal 3424 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 WSoTO>Vg`5>fvis2T9gqzV*d+a<2lp- literal 0 HcmV?d00001 diff --git a/docs/mainpage.dox b/docs/mainpage.dox new file mode 100644 index 0000000000..408117ca5a --- /dev/null +++ b/docs/mainpage.dox @@ -0,0 +1,423 @@ +/****************************************************************************** + * Copyright (c) 2011, Duane Merrill. All rights reserved. + * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the NVIDIA CORPORATION nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + + + +/** + * \mainpage + * + * \tableofcontents + * + * \htmlonly + * + *    + * Download CUB! + *
    + * + *    + * Browse or fork CUB at GitHub! + *
    + * + *    + * Join the cub-users discussion forum! + * \endhtmlonly + * + * \section sec0 (1) What is CUB? + * + * \par + * CUB is a library of high-performance parallel primitives and other utilities for + * constructing CUDA kernel software. CUB enhances productivity, performance, and portability + * by providing an abstraction layer over complex + * [block-level] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#programming-model), + * [warp-level] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#hardware-implementation), and + * [thread-level](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#programming-model) operations. + * + * \par + * CUB's primitives are not bound to any particular width of parallelism or to any particular + * data type. This allows them to be flexible and tunable to fit your kernels' needs. + * Thus CUB is [CUDA Unbound](index.html). + * + * \image html cub_overview.png + * + * \par + * Browse our collections of: + * - [Cooperative primitives](group___simt_coop.html), including: + * - Thread block operations (e.g., radix sort, prefix scan, reduction, etc.) + * - Warp operations (e.g., prefix scan) + * - [SIMT utilities](group___simt_utils.html), including: + * - Tile-based I/O utilities (e.g., for performing {vectorized, coalesced} data movement of {blocked, striped} data tiles) + * - Low-level thread I/O using cache-modifiers + * - Abstractions for thread block work distribution (e.g., work-stealing, even-share, etc.) + * - [Host utilities](group___host_util.html), including: + * - Caching allocator for quick management of device temporaries + * - Device reflection + * + * \section sec2 (2) Recent news + * + * \par + * - [CUB v0.9.1](download_cub.html) (03/09/2013). Intial "preview" release. + * CUB is the first durable, high-performance library + * of cooperative block-level, warp-level, and thread-level primitives for CUDA + * kernel programming. More primitives and examples coming soon! + * + * \section sec3 (3) A simple example + * + * \par + * The following code snippet illustrates a simple CUDA kernel for sorting a thread block's data: + * + * \par + * \code + * #include + * + * // An tile-sorting CUDA kernel + * template < + * int BLOCK_THREADS, // Threads per block + * int ITEMS_PER_THREAD, // Items per thread + * typename T> // Numeric data type + * __global__ void TileSortKernel(T *d_in, T *d_out) + * { + * using namespace cub; + * const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; + * + * // Parameterize cub::BlockRadixSort for the parallel execution context + * typedef BlockRadixSort BlockRadixSort; + * + * // Declare the shared memory needed by BlockRadixSort + * __shared__ typename BlockRadixSort::SmemStorage smem_storage; + * + * // A segment of data items per thread + * T data[ITEMS_PER_THREAD]; + * + * // Load a tile of data using vector-load instructions + * BlockLoadVectorized(data, d_in + (blockIdx.x * TILE_SIZE)); + * + * // Sort data in ascending order + * BlockRadixSort::SortBlocked(smem_storage, data); + * + * // Store the sorted tile using vector-store instructions + * BlockStoreVectorized(data, d_out + (blockIdx.x * TILE_SIZE)); + * } + * \endcode + * + * \par + * The cub::BlockRadixSort type performs a cooperative radix sort across the + * thread block's data items. Its implementation is parameterized by the number of threads per block and the aggregate + * data type \p T and is specialized for the underlying architecture. + * + * \par + * Once instantiated, the cub::BlockRadixSort type exposes an opaque cub::BlockRadixSort::SmemStorage + * member type. The thread block uses this storage type to allocate the shared memory needed by the + * primitive. This storage type can be aliased or union'd with other types so that the + * shared memory can be reused for other purposes. + * + * \par + * Furthermore, the kernel uses CUB's primitives for vectorizing global + * loads and stores. For example, lower-level ld.global.v4.s32 + * [PTX instructions](http://docs.nvidia.com/cuda/parallel-thread-execution) + * will be generated when \p T = \p int and \p ITEMS_PER_THREAD is a multiple of 4. + * + * \section sec4 (4) Why do you need CUB? + * + * \par + * CUDA kernel software is where the complexity of parallelism is expressed. + * Programmers must reason about deadlock, livelock, synchronization, race conditions, + * shared memory layout, plurality of state, granularity, throughput, latency, + * memory bottlenecks, etc. Constructing and fine-tuning kernel code is perhaps the + * most challenging, time-consuming aspect of CUDA programming. + * + * \par + * However, with the exception of CUB, there are few (if any) software libraries of + * reusable kernel primitives. In the CUDA ecosystem, CUB is unique in this regard. + * As a [SIMT](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#hardware-implementation) + * library and software abstraction layer, CUB provides: + * -# Simplicity of composition. Parallel CUB primitives can be simply sequenced + * together in kernel code. (This convenience is analogous to programming with + * [Thrust](http://thrust.github.com/) primitives in the host program.) + * -# High performance. CUB simplifies high performance kernel development by + * taking care to implement and make available the fastest available algorithms, + * strategies, and techniques. + * -# Performance portability. CUB primitives are specialized to match + * the target hardware. Furthermore, the CUB library continually evolves to accommodate new + * algorithmic developments, hardware instructions, etc. + * -# Simplicity of performance tuning. CUB primitives provide parallel abstractions + * whose performance behavior can be statically tuned. For example, most CUB primitives + * support alternative algorithmic strategies and variable grain sizes (threads per block, + * items per thread, etc.). + * -# Robustness and durability. CUB primitives are designed to function properly for + * arbitrary data types and widths of parallelism (not just for the built-in C++ types + * or for powers-of-two threads per block). + * + * \section sec5 (5) Where is CUB positioned in the CUDA ecosystem? + * + * \par + * CUDA's programming model embodies three different levels of program execution, each + * engendering its own abstraction layer in the CUDA software stack (i.e., the "black boxes" + * below): + * + * + * + * + * + * + * + * + * + * + *
    + * \par + * CUDA kernel. A single CPU thread invokes a CUDA kernel to perform + * some data-parallel function. The incorporation of entire kernels (and their + * corresponding invocation stubs) into libraries is the most common form of code reuse for + * CUDA. Libraries of CUDA kernels include the following: + * - [cuBLAS](https://developer.nvidia.com/cublas) + * - [cuFFT](https://developer.nvidia.com/cufft) + * - [cuSPARSE](https://developer.nvidia.com/cusparse) + * - [Thrust](http://thrust.github.com/) + * + * \htmlonly + * + * \endhtmlonly + *
    + * \par + * Thread blocks (SIMT). Each kernel invocation comprises some number of parallel + * threads. Threads are grouped into blocks, and the entire block of threads invokes some cooperative + * function in which they communicate and synchronize with each other. There has historically been very + * little reuse of cooperative SIMT software within CUDA kernel. Libraries of thread-block primitives + * include the following: + * - [CUB](index.html) + * + * \htmlonly + * + * \endhtmlonly + *
    + * \par + * CUDA thread. A single CUDA thread invokes some sequential function. + * This is the finest-grained level of CUDA software abstraction and requires + * no consideration for the scheduling or synchronization of parallel threads. CUDA libraries of + * purely data-parallel functions include the following: + * - [ CUDA Math](http://docs.nvidia.com/cuda/cuda-math-api/index.html), + * [Texture](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#texture-functions), and + * [Atomic](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions) APIs + * - [cuRAND](https://developer.nvidia.com/curand)'s device-code interface + * - [CUB](index.html) + * + * \htmlonly + * + * \endhtmlonly + *
    + * + * + * \section sec6 (6) How does CUB work? + * + * \par + * CUB leverages the following programming idioms: + * -# [C++ templates](index.html#sec3sec1) + * -# [Reflective type structure](index.html#sec3sec2) + * -# [Flexible data mapping](index.html#sec3sec3) + * + * \subsection sec3sec1 6.1    C++ templates + * + * \par + * As a SIMT library, CUB must be flexible enough to accommodate a wide spectrum + * of parallel execution contexts, + * i.e., specific: + * - Data types + * - Widths of parallelism (threads per block) + * - Grain sizes (data items per thread) + * - Underlying architectures (special instructions, warp size, rules for bank conflicts, etc.) + * - Tuning requirements (e.g., latency vs. throughput) + * + * \par + * To provide this flexibility, CUB is implemented as a C++ template library. + * C++ templates are a way to write generic algorithms and data structures. + * There is no need to build CUB separately. You simply \#include the + * cub.cuh header file into your .cu CUDA C++ sources + * and compile with NVIDIA's nvcc compiler. + * + * \subsection sec3sec2 6.2    Reflective type structure + * + * \par + * Cooperation within a thread block requires shared memory for communicating between threads. + * However, the specific size and layout of the memory needed by a given + * primitive will be specific to the details of its parallel execution context (e.g., how + * many threads are calling into it, how many items are processed per thread, etc.). Furthermore, + * this shared memory must be allocated outside of the component itself if it is to be + * reused elsewhere by the thread block. + * + * \par + * \code + * // Parameterize a BlockScan type for use with 128 threads + * // and 4 items per thread + * typedef cub::BlockScan BlockScan; + * + * // Declare shared memory for BlockScan + * __shared__ typename BlockScan::SmemStorage smem_storage; + * + * // A segment of consecutive input items per thread + * int data[4]; + * + * // Obtain data in blocked order + * ... + * + * // Perform an exclusive prefix sum across the tile of data + * BlockScan::ExclusiveSum(smem_storage, data, data); + * + * \endcode + * + * \par + * To address this issue, we encapsulate cooperative procedures within + * reflective type structure (C++ classes). As illustrated in the + * cub::BlockScan example above, these primitives are C++ classes with + * interfaces that expose both: + * - Procedural entrypoints for a block of threads to invoke + * - An opaque shared memory type needed for the operation of those methods + * + * \subsection sec3sec3 6.3    Flexible data mapping + * + * \par + * We often design kernels such that each thread block is assigned a "tile" of data + * items for processing. + * + * \par + * \image html tile.png + *

    Tile of eight ordered data items
    + + * \par + * When the tile size equals the thread block size, the + * mapping of data onto threads is straightforward (one datum per thread). + * However, there are often performance advantages for processing more + * than one datum per thread. For these scenarios, CUB primitives + * support the following alternatives for partitioning data items across + * the block of threads: + * + * + * + * + * + * + * + * + *
    + * \par + * - Blocked arrangement. The aggregate tile of items is partitioned + * evenly across threads in "blocked" fashion with threadi + * owning the ith segment of consecutive elements. + * Blocked arrangements are often desirable for algorithmic benefits (where + * long sequences of items can be processed sequentially within each thread). + * + * \par + * \image html blocked.png + *
    Blocked arrangement across four threads
    (emphasis on items owned by thread0)
    + *
    + * \par + * - Striped arrangement. The aggregate tile of items is partitioned across + * threads in "striped" fashion, i.e., the \p ITEMS_PER_THREAD items owned by + * each thread have logical stride \p BLOCK_THREADS between them. Striped arrangements + * are often desirable for data movement through global memory (where + * [read/write coalescing](http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#coalesced-access-global-memory) + * is an important performance consideration). + * + * \par + * \image html striped.png + *
    Striped arrangement across four threads
    (emphasis on items owned by thread0)
    + *
    + * + * \par + * The benefits of processing multiple items per thread (a.k.a., register blocking, granularity coarsening, etc.) include: + * - Algorithmic efficiency. Sequential work over multiple items in + * thread-private registers is cheaper than synchronized, cooperative + * work through shared memory spaces. + * - Data occupancy. The number of items that can be resident on-chip in + * thread-private register storage is often greater than the number of + * schedulable threads. + * - Instruction-level parallelism. Multiple items per thread also + * facilitates greater ILP for improved throughput and utilization. + * + * \par + * Finally, cub::BlockExchange provides operations for converting between blocked + * and striped arrangements. + * + * \section sec7 (7) Contributors + * + * \par + * CUB is developed as an open-source project by [NVIDIA Research](http://research.nvidia.com). + * The primary contributor is [Duane Merrill](http://github.com/dumerrill). + * + * \section sec8 (8) Open Source License + * + * \par + * CUB is available under the "New BSD" open-source license: + * + * \par + * \code + * Copyright (c) 2011, Duane Merrill. All rights reserved. + * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the NVIDIA CORPORATION nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * \endcode + * + */ + + +/** + * \defgroup Simt SIMT Primitives + */ + +/** + * \defgroup SimtCoop Cooperative SIMT Operations + * \ingroup Simt + */ + +/** + * \defgroup SimtUtils SIMT Utilities + * \ingroup Simt + */ + +/** + * \defgroup HostUtil Host Utilities + */ diff --git a/cub/docs/references.bib b/docs/references.bib similarity index 100% rename from cub/docs/references.bib rename to docs/references.bib diff --git a/cub/test/.gitignore b/test/.gitignore similarity index 100% rename from cub/test/.gitignore rename to test/.gitignore diff --git a/cub/test/Makefile b/test/Makefile similarity index 100% rename from cub/test/Makefile rename to test/Makefile diff --git a/cub/test/test_allocator.cu b/test/test_allocator.cu similarity index 100% rename from cub/test/test_allocator.cu rename to test/test_allocator.cu diff --git a/cub/test/test_block_load_store.cu b/test/test_block_load_store.cu similarity index 100% rename from cub/test/test_block_load_store.cu rename to test/test_block_load_store.cu diff --git a/cub/test/test_block_radix_sort.cu b/test/test_block_radix_sort.cu similarity index 100% rename from cub/test/test_block_radix_sort.cu rename to test/test_block_radix_sort.cu diff --git a/cub/test/test_block_reduce.cu b/test/test_block_reduce.cu similarity index 81% rename from cub/test/test_block_reduce.cu rename to test/test_block_reduce.cu index acde3e0021..daa9825963 100644 --- a/cub/test/test_block_reduce.cu +++ b/test/test_block_reduce.cu @@ -51,21 +51,83 @@ bool g_verbose = false; // Test kernels //--------------------------------------------------------------------- + +/** + * Generic reduction + */ +template < + typename T, + typename ReductionOp, + bool PRIMITIVE = Traits::PRIMITIVE> +struct DeviceTest +{ + template < + typename BlockReduce, + int ITEMS_PER_THREAD> + static __device__ __forceinline__ T Test( + typename BlockReduce::SmemStorage &smem_storage, + T (&data)[ITEMS_PER_THREAD], + ReductionOp &reduction_op) + { + return BlockReduce::Reduce(smem_storage, data, reduction_op); + } + + template < typename BlockReduce> + static __device__ __forceinline__ T Test( + typename BlockReduce::SmemStorage &smem_storage, + T &data, + ReductionOp &reduction_op, + int valid_threads) + { + return BlockReduce::Reduce(smem_storage, data, reduction_op, valid_threads); + } +}; + + +/** + * Sum reduction (only compile for primitive, built-ins only) + */ +template +struct DeviceTest, true> +{ + template < + typename BlockReduce, + int ITEMS_PER_THREAD> + static __device__ __forceinline__ T Test( + typename BlockReduce::SmemStorage &smem_storage, + T (&data)[ITEMS_PER_THREAD], + Sum &reduction_op) + { + return BlockReduce::Sum(smem_storage, data); + } + + template + static __device__ __forceinline__ T Test( + typename BlockReduce::SmemStorage &smem_storage, + T &data, + Sum &reduction_op, + int valid_threads) + { + return BlockReduce::Sum(smem_storage, data, valid_threads); + } +}; + + /** * Test full-tile reduction kernel (where num_elements is an even * multiple of BLOCK_THREADS) */ template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> + int BLOCK_THREADS, + int ITEMS_PER_THREAD, + typename T, + typename ReductionOp> __launch_bounds__ (BLOCK_THREADS, 1) __global__ void FullTileReduceKernel( - T *d_in, - T *d_out, + T *d_in, + T *d_out, ReductionOp reduction_op, - int tiles) + int tiles) { const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; @@ -97,7 +159,7 @@ __global__ void FullTileReduceKernel( block_offset += TILE_SIZE; // Cooperatively reduce the tile's aggregate - T tile_aggregate = BlockReduce::Reduce(smem_storage, data, reduction_op); + T tile_aggregate = DeviceTest::template Test(smem_storage, data, reduction_op); // Reduce threadblock aggregate block_aggregate = reduction_op(block_aggregate, tile_aggregate); @@ -116,13 +178,13 @@ __global__ void FullTileReduceKernel( * Test partial-tile reduction kernel (where num_elements < BLOCK_THREADS) */ template < - int BLOCK_THREADS, - typename T, - typename ReductionOp> + int BLOCK_THREADS, + typename T, + typename ReductionOp> __launch_bounds__ (BLOCK_THREADS, 1) __global__ void PartialTileReduceKernel( - T *d_in, - T *d_out, + T *d_in, + T *d_out, int num_elements, ReductionOp reduction_op) { @@ -142,11 +204,7 @@ __global__ void PartialTileReduceKernel( } // Cooperatively reduce the tile's aggregate - T tile_aggregate = BlockReduce::Reduce( - smem_storage, - partial, - reduction_op, - num_elements); + T tile_aggregate = DeviceTest::template Test(smem_storage, partial, reduction_op, num_elements); // Store data if (threadIdx.x == 0) @@ -192,14 +250,14 @@ void Initialize( */ template < int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> + int ITEMS_PER_THREAD, + typename T, + typename ReductionOp> void TestFullTile( - int gen_mode, - int tiles, - ReductionOp reduction_op, - char *type_string) + int gen_mode, + int tiles, + ReductionOp reduction_op, + char *type_string) { const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; diff --git a/cub/test/test_block_scan.cu b/test/test_block_scan.cu similarity index 100% rename from cub/test/test_block_scan.cu rename to test/test_block_scan.cu diff --git a/cub/test/test_block_serialize.cu b/test/test_block_serialize.cu similarity index 100% rename from cub/test/test_block_serialize.cu rename to test/test_block_serialize.cu diff --git a/cub/test/test_coo_spmv.cu b/test/test_coo_spmv.cu similarity index 100% rename from cub/test/test_coo_spmv.cu rename to test/test_coo_spmv.cu diff --git a/cub/test/test_coo_spmv_double.cu b/test/test_coo_spmv_double.cu similarity index 100% rename from cub/test/test_coo_spmv_double.cu rename to test/test_coo_spmv_double.cu diff --git a/cub/test/test_grid_barrier.cu b/test/test_grid_barrier.cu similarity index 100% rename from cub/test/test_grid_barrier.cu rename to test/test_grid_barrier.cu diff --git a/cub/test/test_util.h b/test/test_util.h similarity index 100% rename from cub/test/test_util.h rename to test/test_util.h diff --git a/cub/test/test_warp_scan.cu b/test/test_warp_scan.cu similarity index 100% rename from cub/test/test_warp_scan.cu rename to test/test_warp_scan.cu