├── AI_ETHICS.md ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING-ARCHIVED.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── assets ├── figure2_resize.gif └── pipeline_8s_timing.gif ├── data ├── ModelNet40.yaml ├── Objaverse_Lvis_Colored.yaml ├── ShapeNet-55.yaml ├── dataset_3d.py ├── dataset_catalog.json ├── labels.json └── templates.json ├── main.py ├── models ├── ULIP_models.py ├── customized_backbone │ └── customized_backbone.py ├── losses.py ├── pointbert │ ├── PointTransformer_8192point.yaml │ ├── ULIP_2_PointBERT_10k_colored_pointclouds.yaml │ ├── checkpoint.py │ ├── dvae.py │ ├── logger.py │ ├── misc.py │ └── point_encoder.py ├── pointmlp │ └── pointMLP.py ├── pointnet2 │ ├── pointnet2.py │ └── pointnet2_utils.py └── pointnext │ ├── PointNeXt │ ├── .github │ │ └── workflows │ │ │ └── main.yml │ ├── .gitignore │ ├── .gitmodules │ ├── LICENSE │ ├── README.md │ ├── cfgs │ │ ├── default.yaml │ │ ├── modelnet40ply2048 │ │ │ ├── assanet-l.yaml │ │ │ ├── deepgcn.yaml │ │ │ ├── default.yaml │ │ │ ├── pix4point.yaml │ │ │ ├── pointmlp.yaml │ │ │ ├── pointnet++.yaml │ │ │ ├── pointnet++_original.yaml │ │ │ └── pointnext-s.yaml │ │ ├── s3dis │ │ │ ├── assanet-l.yaml │ │ │ ├── assanet.yaml │ │ │ ├── deepgcn.yaml │ │ │ ├── default.yaml │ │ │ ├── dgcnn.yaml │ │ │ ├── pointnet++.yaml │ │ │ ├── pointnet++msg.yaml │ │ │ ├── pointnet.yaml │ │ │ ├── pointnext-b.yaml │ │ │ ├── pointnext-l.yaml │ │ │ ├── pointnext-s.yaml │ │ │ └── pointnext-xl.yaml │ │ ├── s3dis_pix4point │ │ │ ├── default.yaml │ │ │ ├── pix4point.yaml │ │ │ └── pix4point_bert.yaml │ │ ├── scannet │ │ │ ├── ASSANet.yaml │ │ │ ├── default.yaml │ │ │ ├── pointnet++.yaml │ │ │ ├── pointnet++_original.yaml │ │ │ ├── pointnext-b.yaml │ │ │ ├── pointnext-l.yaml │ │ │ ├── pointnext-s.yaml │ │ │ └── pointnext-xl.yaml │ │ ├── scanobjectnn │ │ │ ├── default.yaml │ │ │ ├── dgcnn.yaml │ │ │ ├── pointmlp.yaml │ │ │ ├── pointnet++.yaml │ │ │ ├── pointnet.yaml │ │ │ └── pointnext-s.yaml │ │ ├── scanobjectnn_pix4point │ │ │ ├── default.yaml │ │ │ └── pix4point.yaml │ │ ├── shapenetpart │ │ │ ├── default.yaml │ │ │ ├── pointnext-s.yaml │ │ │ ├── pointnext-s_c160.yaml │ │ │ └── pointnext-s_c64.yaml │ │ └── shapenetpart_pix4point │ │ │ ├── default.yaml │ │ │ └── pix4point.yaml │ ├── docs │ │ ├── changes.md │ │ ├── examples │ │ │ ├── modelnet.md │ │ │ ├── s3dis.md │ │ │ ├── scannet.md │ │ │ ├── scanobjectnn.md │ │ │ └── shapenetpart.md │ │ ├── index.md │ │ ├── misc │ │ │ └── wandb.png │ │ ├── modelzoo.md │ │ └── projects │ │ │ ├── misc │ │ │ ├── effects_training_scaling.png │ │ │ ├── pix4point.png │ │ │ ├── pointnext.jpeg │ │ │ ├── s3dis_vis.png │ │ │ └── shapenetpart_vis.png │ │ │ ├── pix4point.md │ │ │ └── pointnext.md │ ├── examples │ │ ├── __init__.py │ │ ├── classification │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── pretrain.py │ │ │ └── train.py │ │ ├── profile.py │ │ ├── segmentation │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── test_s3dis_6fold.py │ │ │ └── vis_results.py │ │ └── shapenetpart │ │ │ ├── __init__.py │ │ │ └── main.py │ ├── install.sh │ ├── mkdocs.yml │ ├── openpoints │ │ ├── .gitignore │ │ ├── README.md │ │ ├── __init__.py │ │ ├── cpp │ │ │ ├── __init__.py │ │ │ ├── chamfer_dist │ │ │ │ ├── __init__.py │ │ │ │ ├── chamfer.cu │ │ │ │ ├── chamfer_cuda.cpp │ │ │ │ ├── setup.py │ │ │ │ └── test.py │ │ │ ├── emd │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── __init__.py │ │ │ │ ├── cuda │ │ │ │ │ ├── emd.cpp │ │ │ │ │ └── emd_kernel.cu │ │ │ │ ├── emd.py │ │ │ │ ├── setup.py │ │ │ │ └── test_emd_loss.py │ │ │ ├── pointnet2_batch │ │ │ │ ├── __init__.py │ │ │ │ ├── setup.py │ │ │ │ └── src │ │ │ │ │ ├── ball_query.cpp │ │ │ │ │ ├── ball_query_gpu.cu │ │ │ │ │ ├── ball_query_gpu.h │ │ │ │ │ ├── cuda_utils.h │ │ │ │ │ ├── group_points.cpp │ │ │ │ │ ├── group_points_gpu.cu │ │ │ │ │ ├── group_points_gpu.h │ │ │ │ │ ├── interpolate.cpp │ │ │ │ │ ├── interpolate_gpu.cu │ │ │ │ │ ├── interpolate_gpu.h │ │ │ │ │ ├── pointnet2_api.cpp │ │ │ │ │ ├── sampling.cpp │ │ │ │ │ ├── sampling_gpu.cu │ │ │ │ │ └── sampling_gpu.h │ │ │ ├── pointops │ │ │ │ ├── __init__.py │ │ │ │ ├── functions │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── pointops.py │ │ │ │ ├── setup.py │ │ │ │ └── src │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── aggregation │ │ │ │ │ ├── aggregation_cuda.cpp │ │ │ │ │ ├── aggregation_cuda_kernel.cu │ │ │ │ │ └── aggregation_cuda_kernel.h │ │ │ │ │ ├── ballquery │ │ │ │ │ ├── ballquery_cuda.cpp │ │ │ │ │ ├── ballquery_cuda_kernel.cu │ │ │ │ │ └── ballquery_cuda_kernel.h │ │ │ │ │ ├── cuda_utils.h │ │ │ │ │ ├── grouping │ │ │ │ │ ├── grouping_cuda.cpp │ │ │ │ │ ├── grouping_cuda_kernel.cu │ │ │ │ │ └── grouping_cuda_kernel.h │ │ │ │ │ ├── interpolation │ │ │ │ │ ├── interpolation_cuda.cpp │ │ │ │ │ ├── interpolation_cuda_kernel.cu │ │ │ │ │ └── interpolation_cuda_kernel.h │ │ │ │ │ ├── knnquery │ │ │ │ │ ├── knnquery_cuda.cpp │ │ │ │ │ ├── knnquery_cuda_kernel.cu │ │ │ │ │ └── knnquery_cuda_kernel.h │ │ │ │ │ ├── pointops_api.cpp │ │ │ │ │ ├── sampling │ │ │ │ │ ├── sampling_cuda.cpp │ │ │ │ │ ├── sampling_cuda_kernel.cu │ │ │ │ │ └── sampling_cuda_kernel.h │ │ │ │ │ └── subtraction │ │ │ │ │ ├── subtraction_cuda.cpp │ │ │ │ │ ├── subtraction_cuda_kernel.cu │ │ │ │ │ └── subtraction_cuda_kernel.h │ │ │ └── subsampling │ │ │ │ ├── cpp_utils │ │ │ │ ├── cloud │ │ │ │ │ ├── cloud.cpp │ │ │ │ │ └── cloud.h │ │ │ │ └── nanoflann │ │ │ │ │ └── nanoflann.hpp │ │ │ │ ├── grid_subsampling │ │ │ │ ├── grid_subsampling.cpp │ │ │ │ └── grid_subsampling.h │ │ │ │ ├── setup.py │ │ │ │ └── wrapper.cpp │ │ ├── dataset │ │ │ ├── __init__.py │ │ │ ├── atom3d │ │ │ │ ├── __init__.py │ │ │ │ └── psr.py │ │ │ ├── build.py │ │ │ ├── data_util.py │ │ │ ├── datalist.py │ │ │ ├── dataset_base.py │ │ │ ├── graph_dataset │ │ │ │ ├── __init__.py │ │ │ │ ├── graph_dataset.py │ │ │ │ ├── stack_with_pad.py │ │ │ │ ├── structural_dataset.py │ │ │ │ └── svd_encodings_dataset.py │ │ │ ├── grid_sample.py │ │ │ ├── matterport3d │ │ │ │ ├── __init__.py │ │ │ │ ├── category_mapping.tsv │ │ │ │ ├── matterport3d.py │ │ │ │ └── matterport3d_dataprocessing.py │ │ │ ├── modelnet │ │ │ │ ├── __init__.py │ │ │ │ ├── modelnet40_normal_resampled_loader.py │ │ │ │ └── modelnet40_ply_2048_loader.py │ │ │ ├── molhiv │ │ │ │ ├── __init__.py │ │ │ │ └── data.py │ │ │ ├── molpcba │ │ │ │ ├── __init__.py │ │ │ │ └── data.py │ │ │ ├── parsers │ │ │ │ ├── __init__.py │ │ │ │ ├── class_map.py │ │ │ │ ├── constants.py │ │ │ │ ├── parser.py │ │ │ │ ├── parser_factory.py │ │ │ │ ├── parser_image_folder.py │ │ │ │ ├── parser_image_in_tar.py │ │ │ │ ├── parser_image_tar.py │ │ │ │ └── parser_tfds.py │ │ │ ├── pcqm4m │ │ │ │ ├── __init__.py │ │ │ │ └── data.py │ │ │ ├── pcqm4mv2 │ │ │ │ ├── __init__.py │ │ │ │ └── data.py │ │ │ ├── s3dis │ │ │ │ ├── __init__.py │ │ │ │ ├── s3dis.py │ │ │ │ ├── s3dis_block.py │ │ │ │ └── s3dis_sphere.py │ │ │ ├── scannetv2 │ │ │ │ ├── __init__.py │ │ │ │ └── scannet.py │ │ │ ├── scanobjectnn │ │ │ │ ├── __init__.py │ │ │ │ └── scanobjectnn.py │ │ │ ├── semantic_kitti │ │ │ │ ├── __init__.py │ │ │ │ ├── compile_op.sh │ │ │ │ ├── helper_tool.py │ │ │ │ ├── label_mapping.yaml │ │ │ │ ├── preprocess │ │ │ │ │ └── data_pre.py │ │ │ │ ├── semantickitti.py │ │ │ │ └── utils │ │ │ │ │ ├── 6_fold_cv.py │ │ │ │ │ ├── cpp_wrappers │ │ │ │ │ ├── compile_wrappers.sh │ │ │ │ │ ├── cpp_subsampling │ │ │ │ │ │ ├── grid_subsampling │ │ │ │ │ │ │ ├── grid_subsampling.cpp │ │ │ │ │ │ │ └── grid_subsampling.h │ │ │ │ │ │ ├── setup.py │ │ │ │ │ │ └── wrapper.cpp │ │ │ │ │ └── cpp_utils │ │ │ │ │ │ ├── cloud │ │ │ │ │ │ ├── cloud.cpp │ │ │ │ │ │ └── cloud.h │ │ │ │ │ │ └── nanoflann │ │ │ │ │ │ └── nanoflann.hpp │ │ │ │ │ ├── data_prepare_s3dis.py │ │ │ │ │ ├── data_prepare_semantic3d.py │ │ │ │ │ ├── data_prepare_semantickitti.py │ │ │ │ │ ├── download_semantic3d.sh │ │ │ │ │ ├── meta │ │ │ │ │ ├── anno_paths.txt │ │ │ │ │ └── class_names.txt │ │ │ │ │ ├── nearest_neighbors │ │ │ │ │ ├── KDTreeTableAdaptor.h │ │ │ │ │ ├── knn.cpp │ │ │ │ │ ├── knn.pyx │ │ │ │ │ ├── knn_.cxx │ │ │ │ │ ├── knn_.h │ │ │ │ │ ├── nanoflann.hpp │ │ │ │ │ ├── setup.py │ │ │ │ │ └── test.py │ │ │ │ │ └── semantic-kitti.yaml │ │ │ ├── shapenet │ │ │ │ ├── __init__.py │ │ │ │ ├── shapenet55.py │ │ │ │ └── shapenetpart.py │ │ │ ├── shapenetpart │ │ │ │ ├── __init__.py │ │ │ │ ├── shapenet55.py │ │ │ │ └── shapenetpart.py │ │ │ ├── vis2d.py │ │ │ └── vis3d.py │ │ ├── loss │ │ │ ├── __init__.py │ │ │ ├── build.py │ │ │ ├── cross_entropy.py │ │ │ └── distill_loss.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── backbone │ │ │ │ ├── Stratified_transformer.py │ │ │ │ ├── __init__.py │ │ │ │ ├── baafnet.py │ │ │ │ ├── ball_dgcnn.py │ │ │ │ ├── curvenet.py │ │ │ │ ├── deepgcn.py │ │ │ │ ├── dgcnn.py │ │ │ │ ├── graphvit3d.py │ │ │ │ ├── grouppointnet.py │ │ │ │ ├── pct.py │ │ │ │ ├── pointmlp.py │ │ │ │ ├── pointnet.py │ │ │ │ ├── pointnetv2.py │ │ │ │ ├── pointnext.py │ │ │ │ ├── pointnextPyG.py │ │ │ │ ├── pointtransformer.py │ │ │ │ ├── pointvit.py │ │ │ │ ├── randlenet.py │ │ │ │ ├── resnet.py │ │ │ │ ├── simpleview.py │ │ │ │ └── simpleview_util.py │ │ │ ├── build.py │ │ │ ├── classification │ │ │ │ ├── __init__.py │ │ │ │ ├── cls_base.py │ │ │ │ └── point_bert.py │ │ │ ├── layers │ │ │ │ ├── __init__.py │ │ │ │ ├── activation.py │ │ │ │ ├── attention.py │ │ │ │ ├── conv.py │ │ │ │ ├── drop.py │ │ │ │ ├── graph_conv.py │ │ │ │ ├── group.py │ │ │ │ ├── group_embed.py │ │ │ │ ├── helpers.py │ │ │ │ ├── kmeans.py │ │ │ │ ├── knn.py │ │ │ │ ├── local_aggregation.py │ │ │ │ ├── mlp.py │ │ │ │ ├── norm.py │ │ │ │ ├── padding.py │ │ │ │ ├── patch_embed.py │ │ │ │ ├── registry.py │ │ │ │ ├── subsample.py │ │ │ │ ├── upsampling.py │ │ │ │ └── weight_init.py │ │ │ ├── reconstruction │ │ │ │ ├── __init__.py │ │ │ │ ├── base_recontruct.py │ │ │ │ ├── maskedpoint.py │ │ │ │ ├── maskedpointgroup.py │ │ │ │ ├── maskedpointvit.py │ │ │ │ └── nodeshuffle.py │ │ │ ├── registry.py │ │ │ └── segmentation │ │ │ │ ├── __init__.py │ │ │ │ ├── base_seg.py │ │ │ │ └── vit_seg.py │ │ ├── optim │ │ │ ├── __init__.py │ │ │ ├── adabelief.py │ │ │ ├── adafactor.py │ │ │ ├── adahessian.py │ │ │ ├── adamp.py │ │ │ ├── adamw.py │ │ │ ├── lamb.py │ │ │ ├── lars.py │ │ │ ├── lookahead.py │ │ │ ├── madgrad.py │ │ │ ├── nadam.py │ │ │ ├── nvnovograd.py │ │ │ ├── optim_factory.py │ │ │ ├── radam.py │ │ │ ├── rmsprop_tf.py │ │ │ └── sgdp.py │ │ ├── scheduler │ │ │ ├── __init__.py │ │ │ ├── cosine_lr.py │ │ │ ├── multistep_lr.py │ │ │ ├── plateau_lr.py │ │ │ ├── poly_lr.py │ │ │ ├── scheduler.py │ │ │ ├── scheduler_factory.py │ │ │ ├── step_lr.py │ │ │ └── tanh_lr.py │ │ ├── transforms │ │ │ ├── __init__.py │ │ │ ├── point_transform_cpu.py │ │ │ ├── point_transformer_gpu.py │ │ │ └── transforms_factory.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── ckpt_util.py │ │ │ ├── config.py │ │ │ ├── dist_utils.py │ │ │ ├── logger.py │ │ │ ├── metrics.py │ │ │ ├── random.py │ │ │ ├── registry.py │ │ │ ├── str2bool.py │ │ │ └── wandb.py │ ├── requirements.txt │ ├── script │ │ ├── download_s3dis.sh │ │ ├── main_classification.sh │ │ ├── main_partseg.sh │ │ ├── main_segmentation.sh │ │ ├── profile_flops.sh │ │ └── test_all_in_one.sh │ └── update.sh │ ├── pointnext-s.yaml │ └── pointnext.py ├── requirements.txt ├── scripts ├── pretrain_pointbert.sh ├── pretrain_pointmlp.sh ├── pretrain_pointnet2_ssg.sh ├── pretrain_pointnext.sh ├── test_pointbert.sh ├── test_pointmlp.sh ├── test_pointnet2_ssg.sh ├── test_pointnext.sh ├── test_ulip2_pointbert_modelnet40.sh └── test_ulip2_pointbert_objaverse_lvis.sh └── utils ├── __init__.py ├── bpe_simple_vocab_16e6.txt.gz ├── build.py ├── config.py ├── io.py ├── logger.py ├── registry.py ├── tokenizer.py └── utils.py /AI_ETHICS.md: -------------------------------------------------------------------------------- 1 | ## Ethics disclaimer for Salesforce AI models, data, code 2 | 3 | This release is for research purposes only in support of an academic 4 | paper. Our models, datasets, and code are not specifically designed or 5 | evaluated for all downstream purposes. We strongly recommend users 6 | evaluate and address potential concerns related to accuracy, safety, and 7 | fairness before deploying this model. We encourage users to consider the 8 | common limitations of AI, comply with applicable laws, and leverage best 9 | practices when selecting use cases, particularly for high-risk scenarios 10 | where errors or misuse could significantly impact people’s lives, rights, 11 | or safety. For further guidance on use cases, refer to our standard 12 | [AUP](https://www.salesforce.com/content/dam/web/en_us/www/documents/legal/Agreements/policies/ExternalFacing_Services_Policy.pdf) 13 | and [AI AUP](https://www.salesforce.com/content/dam/web/en_us/www/documents/legal/Agreements/policies/ai-acceptable-use-policy.pdf). 14 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Comment line immediately above ownership line is reserved for related other information. Please be careful while editing. 2 | #ECCN:Open Source 3 | #GUSINFO:Open Source,Open Source Workflow 4 | -------------------------------------------------------------------------------- /CONTRIBUTING-ARCHIVED.md: -------------------------------------------------------------------------------- 1 | # ARCHIVED 2 | 3 | This project is `Archived` and is no longer actively maintained; 4 | We are not accepting contributions or Pull Requests. 5 | 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Salesforce.com, Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. 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. 11 | 12 | 3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. 15 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | Please report any security issue to [security@salesforce.com](mailto:security@salesforce.com) 4 | as soon as it is discovered. This library limits its runtime dependencies in 5 | order to reduce the total cost of ownership as much as can be, but all consumers 6 | should remain vigilant and have their security stakeholders review all third-party 7 | products (3PP) like this one and their dependencies. 8 | -------------------------------------------------------------------------------- /assets/figure2_resize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/assets/figure2_resize.gif -------------------------------------------------------------------------------- /assets/pipeline_8s_timing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/assets/pipeline_8s_timing.gif -------------------------------------------------------------------------------- /data/ModelNet40.yaml: -------------------------------------------------------------------------------- 1 | NAME: ModelNet 2 | DATA_PATH: data/modelnet40_normal_resampled 3 | NUM_CATEGORY: 40 4 | USE_NORMALS: FALSE -------------------------------------------------------------------------------- /data/Objaverse_Lvis_Colored.yaml: -------------------------------------------------------------------------------- 1 | NAME: Objaverse_Lvis_Colored 2 | DATA_PATH: /export/einstein-vision-hs/3d_vision/objaverse 3 | N_POINTS: 10000 4 | PC_PATH: /export/einstein-vision-hs/3d_vision/objaverse/objaverse_pc_parallel -------------------------------------------------------------------------------- /data/ShapeNet-55.yaml: -------------------------------------------------------------------------------- 1 | NAME: ShapeNet 2 | DATA_PATH: data/shapenet-55 3 | PC_PATH: data/shapenet-55/shapenet_pc 4 | IMAGE_PATH: data/shapenet-55/rendered_images -------------------------------------------------------------------------------- /data/dataset_catalog.json: -------------------------------------------------------------------------------- 1 | { 2 | "shapenet": { 3 | "config": "./data/ShapeNet-55.yaml", 4 | "train": "train", 5 | "test": "test", 6 | "usage": "train" 7 | }, 8 | "modelnet40": { 9 | "config": "./data/ModelNet40.yaml", 10 | "train": "train", 11 | "test": "test", 12 | "usage": "test" 13 | }, 14 | "objaverse_lvis_colored": { 15 | "config": "./data/Objaverse_Lvis_Colored.yaml", 16 | "train": "train", 17 | "test": "test", 18 | "usage": "train" 19 | } 20 | } -------------------------------------------------------------------------------- /data/labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "modelnet40": [ 3 | "airplane", 4 | "bathtub", 5 | "bed", 6 | "bench", 7 | "bookshelf", 8 | "bottle", 9 | "bowl", 10 | "car", 11 | "chair", 12 | "cone", 13 | "cup", 14 | "curtain", 15 | "desk", 16 | "door", 17 | "dresser", 18 | "flower pot", 19 | "glass box", 20 | "guitar", 21 | "keyboard", 22 | "lamp", 23 | "laptop", 24 | "mantel", 25 | "monitor", 26 | "night stand", 27 | "person", 28 | "piano", 29 | "plant", 30 | "radio", 31 | "range hood", 32 | "sink", 33 | "sofa", 34 | "stairs", 35 | "stool", 36 | "table", 37 | "tent", 38 | "toilet", 39 | "tv stand", 40 | "vase", 41 | "wardrobe", 42 | "xbox" 43 | ] 44 | } -------------------------------------------------------------------------------- /models/customized_backbone/customized_backbone.py: -------------------------------------------------------------------------------- 1 | import torch.nn as nn 2 | import torch.nn.functional as F 3 | 4 | class CUSTOMIZED_BACKBONE(nn.Module): 5 | """ 6 | This is a template for defining your customized 3D backbone and use it for pre-training in ULIP framework. 7 | The expected input is Batch_size x num_points x 3, and the expected output is Batch_size x point_cloud_feat_dim 8 | """ 9 | def __init__(self): 10 | pass 11 | 12 | def forward(self, xyz): 13 | pass -------------------------------------------------------------------------------- /models/pointbert/PointTransformer_8192point.yaml: -------------------------------------------------------------------------------- 1 | optimizer : { 2 | type: AdamW, 3 | kwargs: { 4 | lr : 0.0005, 5 | weight_decay : 0.05 6 | }} 7 | 8 | scheduler: { 9 | type: CosLR, 10 | kwargs: { 11 | epochs: 300, 12 | initial_epochs : 10 13 | }} 14 | 15 | model : { 16 | NAME: PointTransformer, 17 | trans_dim: 384, 18 | depth: 12, 19 | drop_path_rate: 0.1, 20 | cls_dim: 40, 21 | num_heads: 6, 22 | group_size: 32, 23 | num_group: 512, 24 | encoder_dims: 256, 25 | } 26 | npoints: 8192 27 | total_bs : 32 28 | step_per_update : 1 29 | max_epoch : 300 30 | grad_norm_clip : 10 31 | 32 | consider_metric: CDL1 -------------------------------------------------------------------------------- /models/pointbert/ULIP_2_PointBERT_10k_colored_pointclouds.yaml: -------------------------------------------------------------------------------- 1 | optimizer : { 2 | type: AdamW, 3 | kwargs: { 4 | lr : 0.0005, 5 | weight_decay : 0.05 6 | }} 7 | 8 | scheduler: { 9 | type: CosLR, 10 | kwargs: { 11 | epochs: 200, 12 | initial_epochs : 10 13 | }} 14 | 15 | model : { 16 | NAME: PointTransformer, 17 | trans_dim: 384, 18 | depth: 18, 19 | drop_path_rate: 0.1, 20 | cls_dim: 40, 21 | num_heads: 6, 22 | group_size: 32, 23 | num_group: 512, 24 | encoder_dims: 256, 25 | } 26 | npoints: 10000 27 | total_bs : 32 28 | step_per_update : 1 29 | max_epoch : 300 30 | grad_norm_clip : 10 31 | 32 | consider_metric: CDL1 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - main 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-python@v2 13 | with: 14 | python-version: 3.x 15 | - run: pip install mkdocs-material mkdocs-awesome-pages-plugin mdx_truly_sane_lists 16 | - run: mkdocs gh-deploy --force 17 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "openpoints"] 2 | path = openpoints 3 | url = git@github.com:guochengqian/openpoints.git 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Guocheng Qian. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/default.yaml: -------------------------------------------------------------------------------- 1 | # distributed 2 | dist_url: tcp://localhost:8888 3 | dist_backend: 'nccl' 4 | multiprocessing_distributed: False 5 | ngpus_per_node: 1 6 | world_size: 1 7 | launcher: 'mp' 8 | local_rank: 0 9 | 10 | use_gpu: True 11 | seed: null 12 | 13 | # ---------------------------------------------------------------------------- # 14 | # Training cfgs 15 | # ---------------------------------------------------------------------------- # 16 | epoch: 0 17 | epochs: 100 18 | 19 | ignore_index: null 20 | val_fn: validate 21 | deterministic: False 22 | sync_bn: False 23 | 24 | criterion_args: 25 | NAME: CrossEntropy 26 | use_mask: False # in some datasets, requiring data mask in input 27 | 28 | grad_norm_clip: null 29 | layer_decay: 0 # no layer decay by default 30 | 31 | step_per_update: 1 32 | start_epoch: 1 33 | sched_on_epoch: True 34 | 35 | # We support wandb for online results collection, please check their documentation for details: https://docs.wandb.ai/ 36 | wandb: 37 | use_wandb: False 38 | 39 | use_amp: False 40 | # ---------------------------------------------------------------------------- # 41 | # Evaluation cfgs 42 | # ---------------------------------------------------------------------------- # 43 | use_voting: False # we do not use any voting. Voting is not a good practice 44 | val_freq: 10 45 | 46 | # ---------------------------------------------------------------------------- # 47 | # io and misc 48 | # ---------------------------------------------------------------------------- # 49 | resume: False 50 | test: False 51 | finetune: False 52 | 53 | mode: train # set to test in evaluation only mode 54 | logname: null 55 | load_path: null 56 | 57 | print_freq: 50 58 | save_freq: -1 # saving frequency for ckpt. -1 only saving the latest and the best. 59 | 60 | root_dir: log/ 61 | pretrained_path: null 62 | 63 | 64 | # ---------------------------------------------------------------------------- # 65 | # data 66 | # ---------------------------------------------------------------------------- # 67 | datatransforms: 68 | train: null 69 | val: null 70 | feature_keys: pos 71 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/assanet-l.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseCls 3 | encoder_args: 4 | NAME: PointNet2Encoder 5 | in_channels: 3 6 | strides: [2, 2, 2, 2] 7 | blocks: [3, 3, 3, 3] 8 | width: 128 9 | width_scaling: 3 10 | double_last_channel: False 11 | layers: 3 12 | use_res: True 13 | query_as_support: True 14 | mlps: null 15 | stem_conv: True 16 | stem_aggr: True 17 | radius: 0.15 18 | radius_scaling: 1.5 19 | block_radius_scaling: 1.5 20 | num_samples: [[20, 36], [20, 36], [20, 36], [20, 36]] 21 | sampler: fps 22 | aggr_args: 23 | NAME: 'ASSA' 24 | feature_type: 'assa' 25 | anisotropic: True 26 | reduction: 'mean' 27 | group_args: 28 | NAME: 'ballquery' 29 | use_xyz: True 30 | normalize_dp: True 31 | conv_args: 32 | order: conv-norm-act 33 | act_args: 34 | act: 'relu' 35 | norm_args: 36 | norm: 'bn' 37 | cls_args: 38 | NAME: ClsHead 39 | num_classes: 40 40 | global_feat: max,avg 41 | mlps: [512, 256] 42 | norm_args: 43 | norm: 'bn1d' 44 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/deepgcn.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 3.88 1.93 2.220 3 | # Throughput (ins./s): 262.8308528647436 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: DeepGCN 9 | in_channels: 3 10 | channels: 64 11 | n_classes: 40 12 | emb_dims: 1024 13 | n_blocks: 14 14 | conv: 'edge' 15 | block: 'res' 16 | k: 9 17 | epsilon: 0.2 18 | use_stochastic: True 19 | use_dilation: True 20 | dropout: 0.5 21 | norm_args: {'norm': 'bn'} 22 | act_args: {'act': 'relu'} 23 | cls_args: 24 | NAME: ClsHead 25 | num_classes: 40 26 | mlps: [512, 256] 27 | norm_args: 28 | norm: 'bn1d' 29 | lr: 30 | 0.1 31 | optimizer: 32 | NAME: momentum 33 | weight_decay: 1.0e-4 34 | momentum: 0.9 35 | filter_bias_and_bn: False 36 | 37 | # scheduler 38 | sched: cosine 39 | epochs: 400 40 | warmup_epochs: 0 41 | warmup_lr: 1.0e-6 42 | min_lr: 0.001 43 | 44 | sync_bn: False -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/default.yaml: -------------------------------------------------------------------------------- 1 | # Dataset Related 2 | num_points: 1024 # number of poins actually used in training and evaluation 3 | dataset: 4 | common: 5 | NAME: ModelNet40Ply2048 6 | data_dir: './data/ModelNet40Ply2048' 7 | train: 8 | split: train 9 | num_points: 1024 # in training, use sampled 1024 points for data augmentation. 10 | val: 11 | split: test 12 | num_points: 1024 # in testing, use uniformly pre-sampled 1024 points for evaluation (following https://github.com/lulutang0608/Point-BERT) 13 | 14 | feature_keys: pos 15 | 16 | datatransforms: 17 | train: [PointsToTensor, PointCloudScaleAndTranslate] # rotation does not help 18 | vote: [PointCloudScaleAndTranslate] 19 | val: [PointsToTensor] 20 | kwargs: 21 | shift: [0.2, 0.2, 0.2] 22 | batch_size: 32 23 | dataloader: 24 | num_workers: 6 25 | 26 | num_classes: 40 27 | # ---------------------------------------------------------------------------- # 28 | # Training cfgs 29 | # ---------------------------------------------------------------------------- # 30 | # training receipe borrowed from: https://github.com/yanx27/Pointnet_Pointnet2_pytorch 31 | 32 | # ---------------------------------------------------------------------------- # 33 | # Training cfgs 34 | # ---------------------------------------------------------------------------- # 35 | # this one is better. 36 | sched: cosine 37 | epochs: 600 38 | warmup_epochs: 0 39 | min_lr: null 40 | 41 | # Training parameters 42 | lr: 0.001 43 | optimizer: 44 | NAME: 'adamw' 45 | weight_decay: 0.05 46 | 47 | grad_norm_clip: 1 48 | 49 | criterion_args: 50 | NAME: SmoothCrossEntropy 51 | label_smoothing: 0.2 52 | 53 | # ---------------------------------------------------------------------------- # 54 | # io and misc 55 | # ---------------------------------------------------------------------------- # 56 | log_dir: 'modelnet40' 57 | print_freq: 10 58 | val_freq: 1 59 | 60 | # ----------------- Model related 61 | val_batch_size: 64 62 | pretrained_path: null 63 | 64 | wandb: 65 | project: PointNeXt-ModelNet40Ply2048 66 | 67 | seed: null -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/pix4point.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseCls 3 | encoder_args: 4 | NAME: PointViT 5 | in_channels: 3 6 | embed_dim: 384 7 | depth: 12 8 | num_heads: 6 9 | mlp_ratio: 4. 10 | drop_rate: 0. 11 | attn_drop_rate: 0.1 12 | drop_path_rate: 0.0 13 | qkv_bias: True 14 | act_args: 15 | act: 'gelu' 16 | norm_args: 17 | norm: 'ln' 18 | eps: 1.0e-6 19 | embed_args: 20 | NAME: PointPatchEmbed 21 | feature_type: 'dp' 22 | reduction: 'max' 23 | sample_ratio: 0.25 # ablation: 0.25 24 | normalize_dp: False 25 | group_size: 32 26 | subsample: 'fps' 27 | group: 'knn' 28 | norm_args: bn # ablation: in 29 | conv_args: 30 | order: conv-norm-act 31 | layers: 4 32 | channels: [128, 256, 512] 33 | global_feat: cls,max,avg 34 | cls_args: 35 | NAME: ClsHead 36 | num_classes: 40 37 | mlps: [256, 256] 38 | norm_args: 39 | norm: 'bn1d' 40 | 41 | pretrained_path: pretrained/imagenet/small_21k_224.pth 42 | mode: finetune_encoder 43 | 44 | 45 | criterion_args: 46 | NAME: SmoothCrossEntropy 47 | label_smoothing: 0.2 48 | 49 | # Optimizer 50 | lr: 5.0e-4 51 | optimizer: 52 | NAME: 'adamw' 53 | weight_decay: 0.05 54 | 55 | # scheduler 56 | epochs: 300 57 | sched: cosine 58 | warmup_epochs: 0 59 | min_lr: 1.0e-6 60 | 61 | wandb: 62 | project: pix4point-modelnet40 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/pointmlp.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 31.36 15.61 13.239 3 | model: 4 | NAME: PointMLP 5 | in_channels: 3 6 | points: 1024 7 | num_classes: 40 8 | embed_dim: 64 9 | groups: 1 10 | res_expansion: 1.0 11 | activation: "relu" 12 | bias: False 13 | use_xyz: False 14 | normalize: "anchor" 15 | dim_expansion: [ 2, 2, 2, 2 ] 16 | pre_blocks: [ 2, 2, 2, 2 ] 17 | pos_blocks: [ 2, 2, 2, 2 ] 18 | k_neighbors: [ 24, 24, 24, 24 ] 19 | reducers: [ 2, 2, 2, 2 ] 20 | 21 | lr: 22 | 0.1 23 | optimizer: 24 | NAME: 'momentum' 25 | momentum: 0.9 26 | weight_decay: 2.0e-4 27 | 28 | sched: cosine 29 | epochs: 300 30 | t_max: 300 31 | min_lr: 0.005 32 | warmup_epochs: 0 # Later change to 10? 33 | 34 | criterion_args: 35 | NAME: SmoothCrossEntropy 36 | label_smoothing: 0.2 37 | 38 | datatransforms: 39 | train: [PointsToTensor, PointCloudScaleAndTranslate] 40 | vote: [PointCloudScaleAndTranslate] 41 | val: [PointsToTensor] 42 | kwargs: 43 | shift: [0.2, 0.2, 0.2] 44 | 45 | batch_size: 32 46 | val_batch_size: 64 47 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/pointnet++.yaml: -------------------------------------------------------------------------------- 1 | # GMACs Params.(M) 2 | # 0.84 1.466 3 | # Throughput (ins./s): 1632.3943616291886 (2080ti, B=48) 4 | # Throughput (ins./s): 2062.428502574422 5 | 6 | model: 7 | NAME: BaseCls 8 | encoder_args: 9 | NAME: PointNet2Encoder 10 | in_channels: 3 11 | width: null 12 | layers: 3 13 | use_res: False 14 | strides: [2, 4, 1] 15 | mlps: [[[64, 64, 128]], # stage 1: 96 16 | [[128, 128, 256]], 17 | [[256, 512, 1024]] 18 | ] # stage 4: 1024 19 | radius: [0.2, 0.4, null] 20 | num_samples: [32, 64, null] 21 | sampler: fps 22 | aggr_args: 23 | NAME: 'convpool' 24 | feature_type: 'dp_fj' 25 | anisotropic: False 26 | reduction: 'max' 27 | group_args: 28 | NAME: 'ballquery' 29 | use_xyz: True 30 | normalize_dp: False 31 | conv_args: 32 | order: conv-norm-act 33 | act_args: 34 | act: 'relu' 35 | norm_args: 36 | norm: 'bn' 37 | cls_args: 38 | NAME: ClsHead 39 | num_classes: 40 40 | mlps: [512, 256] 41 | norm_args: 42 | norm: 'bn1d' 43 | 44 | epochs: 250 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/pointnet++_original.yaml: -------------------------------------------------------------------------------- 1 | # GMACs Params.(M) 2 | # 0.84 1.466 3 | # Throughput (ins./s): 1632.3943616291886 (2080ti, B=48) 4 | # Throughput (ins./s): 2062.428502574422 5 | 6 | model: 7 | NAME: BaseCls 8 | encoder_args: 9 | NAME: PointNet2Encoder 10 | in_channels: 3 11 | width: null 12 | layers: 3 13 | use_res: False 14 | strides: [2, 4, 1] 15 | mlps: [[[64, 64, 128]], # stage 1: 96 16 | [[128, 128, 256]], 17 | [[256, 512, 1024]] 18 | ] # stage 4: 1024 19 | radius: [0.2, 0.4, null] 20 | num_samples: [32, 64, null] 21 | sampler: fps 22 | aggr_args: 23 | NAME: 'convpool' 24 | feature_type: 'dp_fj' 25 | anisotropic: False 26 | reduction: 'max' 27 | group_args: 28 | NAME: 'ballquery' 29 | use_xyz: True 30 | normalize_dp: False 31 | conv_args: 32 | order: conv-norm-act 33 | act_args: 34 | act: 'relu' 35 | norm_args: 36 | norm: 'bn' 37 | cls_args: 38 | NAME: ClsHead 39 | num_classes: 40 40 | mlps: [512, 256] 41 | norm_args: 42 | norm: 'bn1d' 43 | 44 | 45 | # lr_scheduler: 46 | sched: 'step' 47 | decay_epochs: 20 48 | decay_rate: 0.7 49 | sched_on_epoch: True 50 | warmup_epochs: 0 51 | min_lr: 0 52 | 53 | # Training parameters 54 | lr: 0.002 # LR linear rule. 0.002 for 32 batches 55 | optimizer: 56 | NAME: 'adam' 57 | weight_decay: 1.0e-4 58 | betas: [0.9, 0.999] 59 | eps: 1.0e-8 60 | grad_norm_clip: 10 61 | 62 | datatransforms: 63 | train: [PointsToTensor, PointCloudRotation, PointCloudScaleAndTranslate, PointCloudJitter] 64 | vote: [PointCloudRotation, PointCloudScaleAndTranslate, PointCloudJitter] 65 | val: [PointsToTensor] 66 | kwargs: 67 | angle: [0.0, 1.0, 0.0] 68 | gravity_dim: 1 69 | jitter_sigma: 0.01 70 | jitter_clip: 0.05 71 | scale: [0.8, 1.25] 72 | shift: [0.1, 0.1, 0.1] 73 | 74 | criterion_args: 75 | NAME: CrossEntropy 76 | label_smoothing: 0. 77 | 78 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/modelnet40ply2048/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 1.64 0.81 1.374 3 | 4 | # C=64 5 | # GFLOPs GMACs Params.(M) 6 | # 6.49 3.23 4.523 7 | # Throughput (ins./s): 2032.9397323777052 8 | 9 | model: 10 | NAME: BaseCls 11 | encoder_args: 12 | NAME: PointNextEncoder 13 | blocks: [1, 1, 1, 1, 1, 1] 14 | strides: [1, 2, 2, 2, 2, 1] 15 | width: 32 16 | in_channels: 3 17 | radius: 0.15 18 | radius_scaling: 1.5 19 | sa_layers: 2 20 | sa_use_res: True 21 | nsample: 32 22 | expansion: 4 23 | aggr_args: 24 | feature_type: 'dp_fj' 25 | reduction: 'max' 26 | group_args: 27 | NAME: 'ballquery' 28 | normalize_dp: True 29 | conv_args: 30 | order: conv-norm-act 31 | act_args: 32 | act: 'relu' 33 | norm_args: 34 | norm: 'bn' 35 | cls_args: 36 | NAME: ClsHead 37 | num_classes: 40 38 | mlps: [512, 256] 39 | norm_args: 40 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/assanet-l.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 36.20 18.07 115.556 3 | # Throughput (ins./s): 80.94901010205501 4 | 5 | model: 6 | NAME: BaseSeg 7 | encoder_args: 8 | NAME: PointNet2Encoder 9 | in_channels: 4 10 | strides: [4, 4, 4, 4] 11 | blocks: [3, 3, 3, 3] 12 | width: 128 13 | width_scaling: 3 14 | double_last_channel: False 15 | layers: 3 16 | use_res: True 17 | query_as_support: True 18 | mlps: null 19 | stem_conv: True 20 | stem_aggr: True 21 | radius: [[0.1, 0.2], [0.2, 0.4], [0.4, 0.8], [0.8, 1.6]] 22 | num_samples: [[16, 32], [16, 32], [16, 32], [16, 32]] 23 | sampler: fps 24 | aggr_args: 25 | NAME: 'ASSA' 26 | feature_type: 'assa' 27 | anisotropic: True 28 | reduction: 'mean' 29 | group_args: 30 | NAME: 'ballquery' 31 | use_xyz: True 32 | normalize_dp: True 33 | conv_args: 34 | order: conv-norm-act 35 | act_args: 36 | act: 'relu' 37 | norm_args: 38 | norm: 'bn' 39 | decoder_args: 40 | NAME: PointNet2Decoder 41 | fp_mlps: [[64, 64], [128, 128], [256, 256], [512, 512]] 42 | cls_args: 43 | NAME: SegHead 44 | num_classes: 13 45 | in_channels: null 46 | 47 | # ---------------------------------------------------------------------------- # 48 | # Data Augmentation 49 | # ---------------------------------------------------------------------------- # 50 | datatransforms: 51 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudCenterAndNormalize, PointCloudRotation, PointCloudJitter, ChromaticDropGPU, ChromaticNormalize] 52 | val: [PointsToTensor, PointCloudCenterAndNormalize, ChromaticNormalize] 53 | vote: [ChromaticDropGPU] 54 | kwargs: 55 | color_drop: 0.2 56 | gravity_dim: 2 57 | scale: [0.9, 1.1] 58 | angle: [0, 0, 1] 59 | jitter_sigma: 0.005 60 | jitter_clip: 0.02 61 | normalize: False 62 | 63 | # ---------------------------------------------------------------------------- # 64 | # Training cfgs 65 | # ---------------------------------------------------------------------------- # 66 | # training receipe borrowed from: https://github.com/yanx27/Pointnet_Pointnet2_pytorch 67 | criterion_args: 68 | NAME: CrossEntropy 69 | label_smoothing: 0.2 70 | 71 | optimizer: 72 | NAME: 'adamw' # performs 1 point better than adam 73 | weight_decay: 1.0e-4 74 | 75 | # lr_scheduler: 76 | sched: cosine 77 | warmup_epochs: 0 78 | 79 | lr: 0.01 # LR linear rule. 0.002 for 32 batches 80 | min_lr: 1.0e-5 # 81 | 82 | epochs: 150 83 | 84 | batch_size: 8 85 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/deepgcn.yaml: -------------------------------------------------------------------------------- 1 | # FLOPs GMACs Params.(M) 2 | # 99.38 49.32 1.689 3 | # Throughput (ins./s): 2.445071321282616 4 | model: 5 | NAME: BaseSeg 6 | encoder_args: 7 | NAME: DeepGCN 8 | in_channels: 4 9 | channels: 64 10 | emb_dims: 1024 11 | n_blocks: 14 12 | conv: 'edge' 13 | block: 'res' 14 | k: 16 15 | epsilon: 0.2 16 | use_stochastic: True 17 | use_dilation: True 18 | norm_args: {'norm': 'bn'} 19 | act_args: {'act': 'relu'} 20 | is_seg: True 21 | cls_args: 22 | NAME: SegHead 23 | num_classes: 13 24 | mlps: [512, 256] 25 | 26 | batch_size: 8 27 | dataset: 28 | train: 29 | voxel_max: 10000 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/default.yaml: -------------------------------------------------------------------------------- 1 | # data augmentation 2 | dataset: 3 | common: 4 | NAME: S3DIS 5 | data_root: data/S3DIS/s3disfull 6 | test_area: 5 7 | voxel_size: 0.04 8 | train: 9 | split: train 10 | voxel_max: 24000 11 | loop: 30 # here, the training has been looped 30 times. therefore, the training epochs do not need much. 12 | presample: False 13 | val: 14 | split: val 15 | voxel_max: null 16 | presample: True 17 | test: 18 | split: test 19 | voxel_max: null 20 | presample: False 21 | 22 | feature_keys: x,heights 23 | num_classes: 13 24 | batch_size: 32 25 | val_batch_size: 1 26 | 27 | dataloader: 28 | num_workers: 6 29 | 30 | datatransforms: 31 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudXYZAlign, PointCloudRotation, PointCloudJitter, ChromaticDropGPU, ChromaticNormalize] 32 | val: [PointsToTensor, PointCloudXYZAlign, ChromaticNormalize] 33 | vote: [ChromaticDropGPU] 34 | kwargs: 35 | color_drop: 0.2 36 | gravity_dim: 2 37 | scale: [0.9, 1.1] 38 | angle: [0, 0, 1] 39 | jitter_sigma: 0.005 40 | jitter_clip: 0.02 41 | 42 | # ---------------------------------------------------------------------------- # 43 | # Training cfgs 44 | # ---------------------------------------------------------------------------- # 45 | val_fn: validate 46 | ignore_index: null 47 | epochs: 100 48 | 49 | cls_weighed_loss: False 50 | 51 | criterion_args: 52 | NAME: CrossEntropy 53 | label_smoothing: 0.2 54 | 55 | optimizer: 56 | NAME: 'adamw' # performs 1 point better than adam 57 | weight_decay: 1.0e-4 58 | 59 | # lr_scheduler: 60 | sched: cosine 61 | warmup_epochs: 0 62 | 63 | min_lr: 1.0e-5 # 64 | lr: 0.01 # LR linear rule. 65 | 66 | grad_norm_clip: 10 67 | use_voting: False 68 | # ---------------------------------------------------------------------------- # 69 | # io and misc 70 | # ---------------------------------------------------------------------------- # 71 | log_dir: 's3dis' 72 | save_freq: -1 # save epoch every xxx epochs, -1 only save last and best. 73 | val_freq: 1 74 | 75 | wandb: 76 | project: PointNeXt-S3DIS -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/dgcnn.yaml: -------------------------------------------------------------------------------- 1 | # The implementation in DGCNN is not fast. they do not use cuda_knn 2 | 3 | # CUDA_VISIBLE_DEVICES=0 python examples/profile.py batch_size=16 num_points=15000 timing=True --cfg cfgs/s3dis/dgcnn.yaml 4 | # GFLOPs GMACs Params.(M) 5 | # 90.41 44.93 1.278 6 | # Throughput (ins./s): 8.02392738104905 7 | 8 | 9 | # CUDA_VISIBLE_DEVICES=0 python examples/profile.py --cfg cfgs/s3dis/dgcnn.yaml batch_size=64 num_points=2048 model.cls_args.num_classes=50 10 | # # Batches npoints Params.(M) GFLOPs 11 | # # 64 2048 1.288 12.38 12 | # Throughput (ins./s): 197.59781065810753 13 | 14 | model: 15 | NAME: BaseSeg 16 | encoder_args: 17 | NAME: DGCNN 18 | in_channels: 4 19 | channels: 64 20 | emb_dims: 1024 21 | n_blocks: 5 22 | conv: 'edge' 23 | block: 'res' 24 | k: 20 25 | is_seg: True 26 | cls_args: 27 | NAME: SegHead 28 | num_classes: 13 29 | mlps: [512, 256] 30 | act_args: leakyrelu 31 | 32 | batch_size: 8 33 | dataset: 34 | train: 35 | voxel_max: 10000 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnet++.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 7.19 3.53 0.965 3 | # throughput: 186 4 | model: 5 | NAME: BaseSeg 6 | encoder_args: 7 | NAME: PointNet2Encoder 8 | in_channels: 4 9 | width: null 10 | strides: [4, 4, 4, 4] 11 | layers: 3 12 | use_res: False 13 | mlps: [[[32, 32, 64]], # stage 1: 96 14 | [[64, 64, 128]], # stage 2: 256 15 | [[128, 128, 256]], # stage 3: 512 16 | [[256, 256, 512]]] # stage 4: 1024 17 | radius: 0.1 18 | num_samples: 32 19 | sampler: fps 20 | aggr_args: 21 | NAME: 'convpool' 22 | feature_type: 'dp_fj' 23 | anisotropic: False 24 | reduction: 'max' 25 | group_args: 26 | NAME: 'ballquery' 27 | use_xyz: True 28 | conv_args: 29 | order: conv-norm-act 30 | act_args: 31 | act: 'relu' 32 | norm_args: 33 | norm: 'bn' 34 | decoder_args: 35 | NAME: PointNet2Decoder 36 | fp_mlps: [[128, 128, 128], [256, 128], [256, 256], [256, 256]] 37 | cls_args: 38 | NAME: SegHead 39 | num_classes: 13 40 | in_channels: null 41 | 42 | datatransforms: 43 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudXYZAlign, PointCloudJitter, ChromaticDropGPU, ChromaticNormalize] 44 | val: [PointsToTensor, PointCloudXYZAlign, ChromaticNormalize] 45 | vote: [ChromaticDropGPU] 46 | kwargs: 47 | color_drop: 0.2 48 | gravity_dim: 2 49 | scale: [0.9, 1.1] 50 | jitter_sigma: 0.005 51 | jitter_clip: 0.02 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnet.yaml: -------------------------------------------------------------------------------- 1 | # Batches npoints GFLOPs GMACs Params.(M) 2 | # 16 15000 35.50 17.61 3.554 3 | # Throughput (ins./s): 161.58460282387296 4 | 5 | # Batches npoints Params.(M) GFLOPs 6 | # 64 2048 3.558 4.87 7 | # Throughput (ins./s): 1184.83357339522 8 | 9 | model: 10 | NAME: BaseSeg 11 | encoder_args: 12 | NAME: PointNetEncoder 13 | in_channels: 7 14 | is_seg: True 15 | cls_args: 16 | NAME: SegHead 17 | num_classes: 13 18 | mlps: [512, 256, 128, 128] 19 | 20 | datatransforms: 21 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudXYZAlign, ChromaticDropGPU, ChromaticNormalize] 22 | val: [PointsToTensor, PointCloudXYZAlign, ChromaticNormalize] 23 | vote: [ChromaticDropGPU] 24 | kwargs: 25 | color_drop: 0.2 26 | gravity_dim: 2 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnext-b.yaml: -------------------------------------------------------------------------------- 1 | # Model Information 2 | # GFLOPs GMACs Params.(M) 3 | # 8.94 4.41 3.828 4 | # Throughput (ins./s): 158.12545008110516 5 | 6 | model: 7 | NAME: BaseSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [1, 2, 3, 2, 2] 11 | strides: [1, 4, 4, 4, 4] 12 | sa_layers: 1 13 | sa_use_res: False 14 | width: 32 15 | in_channels: 4 16 | expansion: 4 17 | radius: 0.1 18 | nsample: 32 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | decoder_args: 32 | NAME: PointNextDecoder 33 | cls_args: 34 | NAME: SegHead 35 | num_classes: 13 36 | in_channels: null 37 | norm_args: 38 | norm: 'bn' 39 | 40 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnext-l.yaml: -------------------------------------------------------------------------------- 1 | # Model Information 2 | # GFLOPs GMACs Params.(M) 3 | # 15.24 7.53 7.125 4 | # Throughput (ins./s): 115.24562648667185 5 | 6 | model: 7 | NAME: BaseSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [1, 3, 5, 3, 3] 11 | strides: [1, 4, 4, 4, 4] 12 | sa_layers: 1 13 | sa_use_res: False 14 | width: 32 15 | in_channels: 4 16 | expansion: 4 17 | radius: 0.1 18 | nsample: 32 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | decoder_args: 32 | NAME: PointNextDecoder 33 | cls_args: 34 | NAME: SegHead 35 | num_classes: 13 36 | in_channels: null 37 | norm_args: 38 | norm: 'bn' 39 | 40 | batch_size: 8 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | # Model Information 2 | # GFLOPs GMACs Params.(M) 3 | # 3.64 1.79 0.792 4 | # Throughput (ins./s): 226.73038739659074 5 | 6 | model: 7 | NAME: BaseSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [1, 1, 1, 1, 1] 11 | strides: [1, 4, 4, 4, 4] 12 | sa_layers: 2 13 | sa_use_res: True 14 | width: 32 15 | in_channels: 4 16 | expansion: 4 17 | radius: 0.1 18 | nsample: 32 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | decoder_args: 32 | NAME: PointNextDecoder 33 | cls_args: 34 | NAME: SegHead 35 | num_classes: 13 36 | in_channels: null 37 | norm_args: 38 | norm: 'bn' 39 | 40 | 41 | # do not conduct rotation in small model. 42 | datatransforms: 43 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudXYZAlign, PointCloudJitter, ChromaticDropGPU, ChromaticNormalize] 44 | val: [PointsToTensor, PointCloudXYZAlign, ChromaticNormalize] 45 | vote: [ChromaticDropGPU] 46 | kwargs: 47 | color_drop: 0.2 48 | gravity_dim: 2 49 | scale: [0.9, 1.1] 50 | jitter_sigma: 0.005 51 | jitter_clip: 0.02 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis/pointnext-xl.yaml: -------------------------------------------------------------------------------- 1 | # Model Information 2 | # GFLOPs Params.(M) 3 | # 84.81 41.576 4 | # Throughput (ins./s): 46.06739325463371 5 | 6 | model: 7 | NAME: BaseSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [1, 4, 7, 4, 4] 11 | strides: [1, 4, 4, 4, 4] 12 | sa_layers: 1 13 | sa_use_res: False 14 | width: 64 15 | in_channels: 4 16 | expansion: 4 17 | radius: 0.1 18 | nsample: 32 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | decoder_args: 32 | NAME: PointNextDecoder 33 | cls_args: 34 | NAME: SegHead 35 | num_classes: 13 36 | in_channels: null 37 | norm_args: 38 | norm: 'bn' 39 | 40 | batch_size: 8 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis_pix4point/default.yaml: -------------------------------------------------------------------------------- 1 | # data augmentation 2 | dataset: 3 | common: 4 | NAME: S3DISSphere 5 | data_root: './data/S3DIS/Stanford3dDataset_v1.2' 6 | num_points: 16384 7 | in_radius: 2.0 8 | num_steps: 2000 # number of spheres for one training epoch. 9 | voxel_size: 0.04 10 | color_to_255: True 11 | train: 12 | split: train 13 | num_epochs: 600 14 | val: 15 | split: val 16 | num_epochs: 20 17 | num_classes: 13 18 | batch_size: 8 19 | dataloader: 20 | num_workers: 6 21 | 22 | feature_keys: pos,x,heights 23 | 24 | use_mask: True 25 | criterion_args: 26 | NAME: CrossEntropy 27 | label_smoothing: 0.2 28 | # ---------------------------------------------------------------------------- # 29 | # Training cfgs 30 | # ---------------------------------------------------------------------------- # 31 | val_fn: validate_sphere 32 | val_freq: 10 33 | 34 | ignore_index: 255 35 | epochs: 600 36 | optimizer: 37 | NAME: 'adamw' # performs 1 point better than adam 38 | weight_decay: 1.0e-4 39 | 40 | # lr_scheduler: 41 | sched: cosine 42 | warmup_epochs: 10 43 | 44 | lr: 1.0e-4 # LR linear rule. 0.002 for 32 batches 45 | min_lr: 1.0e-6 46 | 47 | grad_norm_clip: 10 48 | use_voting: False 49 | 50 | datatransforms: 51 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudRotation, PointCloudJitter, ChromaticDropGPU, ChromaticNormalize] 52 | val: [PointsToTensor, ChromaticNormalize] 53 | vote: [ChromaticDropGPU] 54 | kwargs: 55 | color_drop: 0.2 56 | gravity_dim: 2 57 | scale: [0.9, 1.1] 58 | jitter_sigma: 0.005 59 | jitter_clip: 0.02 60 | angle: [0, 0, 1] 61 | 62 | 63 | # ---------------------------------------------------------------------------- # 64 | # io and misc 65 | # ---------------------------------------------------------------------------- # 66 | save_freq: -1 # save epoch every xxx epochs, -1 only save last and best. 67 | 68 | log_dir: log/s3dis/pix4point 69 | wandb: 70 | project: pix4point-S3DIS 71 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis_pix4point/pix4point.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointViT 5 | in_channels: 7 6 | embed_dim: 384 7 | depth: 12 8 | num_heads: 6 9 | mlp_ratio: 4. 10 | drop_rate: 0. 11 | attn_drop_rate: 0.0 12 | drop_path_rate: 0.1 13 | add_pos_each_block: True 14 | qkv_bias: True 15 | act_args: 16 | act: 'gelu' # better than relu 17 | norm_args: 18 | norm: 'ln' 19 | eps: 1.0e-6 20 | embed_args: 21 | NAME: P3Embed 22 | feature_type: 'dp_df' # show an abaltion study of this. 23 | reduction: 'max' 24 | sample_ratio: 0.0625 25 | normalize_dp: False 26 | group_size: 32 27 | subsample: 'fps' # random, FPS 28 | group: 'knn' # change it to group args. 29 | conv_args: 30 | order: conv-norm-act 31 | layers: 4 32 | norm_args: 33 | norm: 'ln2d' 34 | decoder_args: 35 | NAME: PointViTDecoder 36 | channel_scaling: 1 37 | global_feat: cls,max 38 | progressive_input: True 39 | cls_args: 40 | NAME: SegHead 41 | num_classes: 13 42 | in_channels: null 43 | mlps: [256] 44 | norm_args: 45 | norm: 'ln1d' 46 | 47 | mode: finetune_encoder 48 | pretrained_path: pretrained/imagenet/mae_s.pth 49 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/s3dis_pix4point/pix4point_bert.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointViT 5 | in_channels: 3 6 | embed_dim: 512 7 | depth: 8 8 | num_heads: 8 9 | mlp_ratio: 4. 10 | drop_rate: 0. 11 | attn_drop_rate: 0.0 12 | drop_path_rate: 0.1 13 | add_pos_each_block: True 14 | qkv_bias: True 15 | act_args: 16 | act: 'gelu' # better than relu 17 | norm_args: 18 | norm: 'ln' 19 | eps: 1.0e-6 20 | embed_args: 21 | NAME: P3Embed 22 | feature_type: 'dp_df' # show an abaltion study of this. 23 | reduction: 'max' 24 | sample_ratio: 0.0625 25 | normalize_dp: False 26 | group_size: 32 27 | subsample: 'fps' # random, FPS 28 | group: 'knn' # change it to group args. 29 | conv_args: 30 | order: conv-norm-act 31 | layers: 4 32 | norm_args: 33 | norm: 'ln2d' 34 | decoder_args: 35 | NAME: PointViTDecoder 36 | channel_scaling: 1 37 | global_feat: cls,max 38 | progressive_input: True 39 | cls_args: 40 | NAME: SegHead 41 | num_classes: 13 42 | in_channels: null 43 | mlps: [256] 44 | norm_args: 45 | norm: 'ln1d' 46 | 47 | mode: finetune_encoder 48 | pretrained_path: pretrained/bert_m_l8c512.bin 49 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/ASSANet.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNet2Encoder 5 | in_channels: 4 6 | strides: [4, 4, 4, 4] 7 | blocks: [3, 3, 3, 3] 8 | width_scaling: 3 9 | layers: 3 10 | use_res: True 11 | query_as_support: True 12 | mlps: [[[16, 16, 32], [32, 32, 64]], 13 | [[64, 64, 128], [64, 96, 128]], 14 | [[128, 196, 256], [128, 196, 256]], 15 | [[256, 256, 512], [256, 384, 512]]] 16 | stem_conv: True 17 | stem_aggr: True 18 | radius: [[0.1, 0.2], [0.2, 0.4], [0.4, 0.8], [0.8, 1.6]] 19 | num_samples: [[16, 32], [16, 32], [16, 32], [16, 32]] 20 | sampler: fps 21 | aggr_args: 22 | NAME: 'ASSA' 23 | feature_type: 'assa' 24 | anisotropic: True 25 | reduction: 'mean' 26 | group_args: 27 | NAME: 'ballquery' 28 | use_xyz: True 29 | normalize_dp: True 30 | conv_args: 31 | order: conv-norm-act 32 | act_args: 33 | act: 'relu' 34 | norm_args: 35 | norm: 'bn' 36 | decoder_args: 37 | NAME: PointNet2Decoder 38 | fp_mlps: [[64, 64], [128, 128], [256, 256], [512, 512]] 39 | cls_args: 40 | NAME: SegHead 41 | num_classes: 20 42 | in_channels: null 43 | 44 | # ---------------------------------------------------------------------------- # 45 | # Data Augmentation 46 | # ---------------------------------------------------------------------------- # 47 | datatransforms: 48 | train: [ChromaticAutoContrast, PointsToTensor, PointCloudScaling, PointCloudCenterAndNormalize, PointCloudRotation, PointCloudJitter, ChromaticDropGPU] 49 | val: [PointsToTensor, PointCloudXYZAlign] 50 | vote: [ChromaticDropGPU] 51 | kwargs: 52 | color_drop: 0.2 53 | gravity_dim: 2 54 | scale: [0.9, 1.1] 55 | angle: [0, 0, 1] 56 | jitter_sigma: 0.005 57 | jitter_clip: 0.02 58 | normalize: False 59 | 60 | 61 | # ---------------------------------------------------------------------------- # 62 | # Training cfgs 63 | # ---------------------------------------------------------------------------- # 64 | # training receipe borrowed from: https://github.com/yanx27/Pointnet_Pointnet2_pytorch 65 | criterion_args: 66 | NAME: CrossEntropy 67 | label_smoothing: 0.2 68 | 69 | optimizer: 70 | NAME: 'adamw' # performs 1 point better than adam 71 | weight_decay: 1.0e-4 72 | 73 | # lr_scheduler: 74 | sched: cosine 75 | warmup_epochs: 0 76 | 77 | lr: 0.02 # LR linear rule. 0.002 for 32 batches 78 | min_lr: 1.0e-5 # 79 | 80 | batch_size: 16 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/default.yaml: -------------------------------------------------------------------------------- 1 | # data augmentation 2 | dataset: 3 | common: 4 | NAME: ScanNet 5 | data_root: data/ScanNet 6 | voxel_size: 0.02 7 | train: 8 | split: train 9 | voxel_max: 64000 # using 32000 points can make training faster but achieves ~0.5 miou lower for PointNeXt-XL 10 | loop: 6 11 | val: 12 | split: val 13 | voxel_max: null 14 | presample: True 15 | test: 16 | split: val 17 | voxel_max: null 18 | 19 | no_label: False 20 | 21 | feature_keys: pos,x,heights # appending heights has insiginificant effects on ScanNet 22 | 23 | num_classes: 20 24 | batch_size: 2 25 | val_batch_size: 1 26 | 27 | dataloader: 28 | num_workers: 6 29 | 30 | datatransforms: 31 | train: [RandomRotateZ, RandomScale, ChromaticAutoContrast, RandomDropFeature, NumpyChromaticNormalize] 32 | val: [NumpyChromaticNormalize] 33 | test: [PointsToTensor, NumpyChromaticNormalize] 34 | vote: [ChromaticDropGPU] 35 | kwargs: 36 | color_drop: 0.2 37 | gravity_dim: 2 38 | rotate_dim: 2 39 | scale: [0.8, 1.2] 40 | mirror: [0.2, -1, -1] 41 | angle: 1 42 | color_mean: [0.46259782, 0.46253258, 0.46253258] # better than not add 43 | color_std: [0.693565 , 0.6852543 , 0.68061745] 44 | 45 | # ---------------------------------------------------------------------------- # 46 | # Training cfgs 47 | # ---------------------------------------------------------------------------- # 48 | val_fn: validate 49 | ignore_index: -100 50 | epochs: 100 51 | 52 | cls_weighed_loss: False 53 | criterion_args: 54 | NAME: CrossEntropy 55 | label_smoothing: 0.0 56 | ignore_index: -100 57 | 58 | optimizer: 59 | NAME: 'adamw' # better than adam 60 | weight_decay: 1.0e-4 # better than 0.5 61 | 62 | # lr_scheduler: 63 | lr: 0.001 64 | min_lr: null 65 | 66 | sched: multistep 67 | decay_epochs: [70, 90] 68 | decay_rate: 0.1 69 | warmup_epochs: 0 70 | 71 | grad_norm_clip: 10 72 | use_voting: False 73 | # ---------------------------------------------------------------------------- # 74 | # io and misc 75 | # ---------------------------------------------------------------------------- # 76 | save_freq: -1 # save epoch every xxx epochs, -1 only save last and best. 77 | val_freq: 1 78 | 79 | wandb: 80 | project: PointNeXt-ScanNet -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnet++.yaml: -------------------------------------------------------------------------------- 1 | # Batches npoints Params.(M) GFLOPs 2 | # 4 45056 0.966 21.67 3 | # Throughput (ins./s): 12.896272793774534 4 | 5 | model: 6 | NAME: BaseSeg 7 | encoder_args: 8 | NAME: PointNet2Encoder 9 | in_channels: 7 10 | width: null 11 | strides: [4, 4, 4, 4] 12 | layers: 3 13 | use_res: False 14 | mlps: [[[32, 32, 64]], # stage 1: 96 15 | [[64, 64, 128]], # stage 2: 256 16 | [[128, 128, 256]], # stage 3: 512 17 | [[256, 256, 512]]] # stage 4: 1024 18 | radius: 0.05 19 | num_samples: 32 20 | sampler: fps 21 | aggr_args: 22 | NAME: 'convpool' 23 | feature_type: 'dp_fj' 24 | anisotropic: False 25 | reduction: 'max' 26 | group_args: 27 | NAME: 'ballquery' 28 | conv_args: 29 | order: conv-norm-act 30 | act_args: 31 | act: 'relu' 32 | norm_args: 33 | norm: 'bn' 34 | decoder_args: 35 | NAME: PointNet2Decoder 36 | fp_mlps: [[128, 128, 128], [256, 128], [256, 256], [256, 256]] 37 | cls_args: 38 | NAME: SegHead 39 | num_classes: 20 40 | in_channels: null 41 | 42 | feature_keys: pos,x,heights -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnet++_original.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNet2Encoder 5 | in_channels: 6 6 | width: null 7 | strides: [4, 4, 4, 4] 8 | layers: 3 9 | use_res: False 10 | mlps: [[[32, 32, 64]], # stage 1: 96 11 | [[64, 64, 128]], # stage 2: 256 12 | [[128, 128, 256]], # stage 3: 512 13 | [[256, 256, 512]]] # stage 4: 1024 14 | radius: 0.1 15 | num_samples: 32 16 | sampler: fps 17 | aggr_args: 18 | NAME: 'convpool' 19 | feature_type: 'dp_fj' 20 | anisotropic: False 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | use_xyz: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | decoder_args: 32 | NAME: PointNet2Decoder 33 | fp_mlps: [[128, 128, 128], [256, 128], [256, 256], [256, 256]] 34 | cls_args: 35 | NAME: SegHead 36 | num_classes: 20 37 | in_channels: null 38 | 39 | class_weights: null 40 | criterion_args: 41 | NAME: CrossEntropy 42 | label_smoothing: 0.0 43 | 44 | # training receipe borrowed from: https://github.com/yanx27/Pointnet_Pointnet2_pytorch 45 | # lr_scheduler: 46 | sched: 'step' 47 | decay_epochs: 10 48 | decay_rate: 0.7 49 | sched_on_epoch: True 50 | warmup_epochs: 0 51 | min_lr: 0 52 | 53 | # Training parameters 54 | batch_size: 32 55 | lr: 0.002 56 | optimizer: 57 | NAME: 'adam' 58 | weight_decay: 1.0e-4 59 | betas: [0.9, 0.999] 60 | eps: 1.0e-8 61 | momentum: 0.98 62 | 63 | grad_norm_clip: 10 64 | 65 | 66 | # data augmentation from 67 | # https://github.com/yanx27/Pointnet_Pointnet2_pytorch/blob/e365b9f7b9c3d7d6444278d92e298e3f078794e1/train_semseg.py#L184 68 | datatransforms: 69 | train: [PointsToTensor, PointCloudXYZAlign, PointCloudRotation] 70 | vote: null 71 | val: [PointsToTensor, PointCloudXYZAlign] 72 | kwargs: 73 | angle: [0, 0, 1] 74 | gravity_dim: 2 75 | 76 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnext-b.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNextEncoder 5 | blocks: [1, 2, 3, 2, 2] 6 | strides: [1, 4, 4, 4, 4] 7 | sa_layers: 1 8 | sa_use_res: False 9 | width: 32 10 | in_channels: 7 11 | expansion: 4 12 | radius: 0.05 13 | nsample: 32 14 | aggr_args: 15 | feature_type: 'dp_fj' 16 | reduction: 'max' 17 | group_args: 18 | NAME: 'ballquery' 19 | normalize_dp: True 20 | conv_args: 21 | order: conv-norm-act 22 | act_args: 23 | act: 'relu' 24 | norm_args: 25 | norm: 'bn' 26 | decoder_args: 27 | NAME: PointNextDecoder 28 | cls_args: 29 | NAME: SegHead 30 | global_feat: max # append global feature to each point feature 31 | num_classes: 20 32 | in_channels: null 33 | norm_args: 34 | norm: 'bn' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnext-l.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNextEncoder 5 | blocks: [1, 3, 5, 3, 3] 6 | strides: [1, 4, 4, 4, 4] 7 | sa_layers: 1 8 | sa_use_res: False 9 | width: 32 10 | in_channels: 7 11 | expansion: 4 12 | radius: 0.05 13 | nsample: 32 14 | aggr_args: 15 | feature_type: 'dp_fj' 16 | reduction: 'max' 17 | group_args: 18 | NAME: 'ballquery' 19 | normalize_dp: True 20 | conv_args: 21 | order: conv-norm-act 22 | act_args: 23 | act: 'relu' 24 | norm_args: 25 | norm: 'bn' 26 | decoder_args: 27 | NAME: PointNextDecoder 28 | cls_args: 29 | NAME: SegHead 30 | global_feat: max # append global feature to each point feature 31 | num_classes: 20 32 | in_channels: null 33 | norm_args: 34 | norm: 'bn' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNextEncoder 5 | blocks: [1, 1, 1, 1, 1] 6 | strides: [1, 4, 4, 4, 4] 7 | sa_layers: 3 8 | sa_use_res: False 9 | width: 32 10 | in_channels: 7 11 | expansion: 4 12 | radius: 0.05 13 | nsample: 32 14 | aggr_args: 15 | feature_type: 'dp_fj' 16 | reduction: 'max' 17 | group_args: 18 | NAME: 'ballquery' 19 | normalize_dp: True 20 | conv_args: 21 | order: conv-norm-act 22 | act_args: 23 | act: 'relu' 24 | norm_args: 25 | norm: 'bn' 26 | decoder_args: 27 | NAME: PointNextDecoder 28 | cls_args: 29 | NAME: SegHead 30 | num_classes: 20 31 | global_feat: max # append global feature to each point feature 32 | in_channels: null 33 | norm_args: 34 | norm: 'bn' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scannet/pointnext-xl.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseSeg 3 | encoder_args: 4 | NAME: PointNextEncoder 5 | blocks: [1, 4, 7, 4, 4] 6 | strides: [1, 4, 4, 4, 4] 7 | sa_layers: 1 8 | sa_use_res: False 9 | width: 64 # can be even larger. 10 | in_channels: 7 # no heights, 1 miou worse 11 | expansion: 4 12 | radius: 0.05 # better than other radius 13 | nsample: 32 14 | aggr_args: 15 | feature_type: 'dp_fj' 16 | reduction: 'max' 17 | group_args: 18 | NAME: 'ballquery' 19 | normalize_dp: True 20 | conv_args: 21 | order: conv-norm-act 22 | act_args: 23 | act: 'relu' 24 | norm_args: 25 | norm: 'bn' 26 | decoder_args: 27 | NAME: PointNextDecoder 28 | cls_args: 29 | NAME: SegHead 30 | global_feat: max # append global feature to each point feature 31 | num_classes: 20 32 | in_channels: null 33 | norm_args: 34 | norm: 'bn' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/default.yaml: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- # 2 | # Dataset cfgs 3 | # ---------------------------------------------------------------------------- # 4 | dataset: 5 | common: 6 | NAME: ScanObjectNNHardest 7 | data_dir: './data/ScanObjectNN/h5_files/main_split' 8 | train: 9 | split: train 10 | val: 11 | split: val 12 | num_points: 1024 13 | 14 | num_points: 1024 # the number of points passed into model 15 | num_classes: &nclass 16 | 15 17 | 18 | datatransforms: 19 | train: [PointsToTensor, PointCloudScaling, PointCloudCenterAndNormalize, PointCloudRotation] 20 | vote: [PointCloudRotation] 21 | val: [PointsToTensor, PointCloudCenterAndNormalize] 22 | kwargs: 23 | scale: [0.9, 1.1] 24 | angle: [0.0, 1.0, 0.0] 25 | gravity_dim: 1 26 | 27 | batch_size: 32 28 | val_batch_size: 64 29 | dataloader: 30 | num_workers: 6 31 | 32 | # ---------------------------------------------------------------------------- # 33 | # Training cfgs 34 | # ---------------------------------------------------------------------------- # 35 | # scheduler 36 | criterion_args: 37 | NAME: SmoothCrossEntropy 38 | label_smoothing: 0.3 39 | 40 | # Optimizer 41 | lr: 0.002 42 | optimizer: 43 | NAME: 'adamw' 44 | weight_decay: 0.05 45 | 46 | sched: cosine 47 | epochs: 250 48 | warmup_epochs: 0 49 | min_lr: 1.0e-4 50 | t_max: 200 51 | 52 | grad_norm_clip: 10 53 | 54 | # ---------------------------------------------------------------------------- # 55 | # io and misc 56 | # ---------------------------------------------------------------------------- # 57 | log_dir: 'scanobjectnn' 58 | print_freq: 10 59 | val_freq: 1 60 | # ----------------- Model related 61 | pretrained_path: null 62 | 63 | wandb: 64 | project: PointNeXt-ScanObjectNN -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/dgcnn.yaml: -------------------------------------------------------------------------------- 1 | # FLOPs GMACs Params.(M) 2 | # 4.82 2.39 1.803 3 | # Throughput (ins./s): 402.31050637074657 (v100) 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: DGCNN 9 | in_channels: 4 10 | channels: 64 11 | n_classes: 40 12 | emb_dims: 1024 13 | n_blocks: 5 14 | conv: 'edge' 15 | k: 20 16 | dropout: 0.5 17 | norm_args: {'norm': 'bn'} 18 | act_args: {'act': 'leakyrelu', 'negative_slope': 0.2} 19 | cls_args: 20 | NAME: ClsHead 21 | num_classes: 15 22 | mlps: [512, 256] 23 | norm_args: 24 | norm: 'bn1d' 25 | 26 | 27 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/pointmlp.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 31.38 15.62 13.231 3 | # Throughput (ins./s): 191.1017802985554 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: PointMLPEncoder 9 | in_channels: 4 10 | embed_dim: 64 11 | groups: 1 12 | res_expansion: 1.0 13 | activation: "relu" 14 | bias: False 15 | use_xyz: False 16 | normalize: "anchor" 17 | dim_expansion: [ 2, 2, 2, 2 ] 18 | pre_blocks: [ 2, 2, 2, 2 ] 19 | pos_blocks: [ 2, 2, 2, 2 ] 20 | k_neighbors: [ 24, 24, 24, 24 ] 21 | reducers: [ 2, 2, 2, 2 ] 22 | cls_args: 23 | NAME: ClsHead 24 | num_classes: 15 25 | mlps: [512, 256] 26 | norm_args: 27 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/pointnet++.yaml: -------------------------------------------------------------------------------- 1 | # FLOPs GMACs Params.(M) 2 | # 1.71 0.84 1.466 3 | # Throughput (ins./s): 1871.6241552204262 4 | model: 5 | NAME: BaseCls 6 | encoder_args: 7 | NAME: PointNet2Encoder 8 | in_channels: 4 9 | width: null 10 | layers: 3 11 | use_res: False 12 | strides: [2, 4, 1] 13 | mlps: [[[64, 64, 128]], # stage 1: 96 14 | [[128, 128, 256]], 15 | [[256, 512, 1024]] 16 | ] # stage 4: 1024 17 | radius: [0.2, 0.4, null] 18 | num_samples: [32, 64, null] 19 | sampler: fps 20 | aggr_args: 21 | NAME: 'convpool' 22 | feature_type: 'dp_fj' 23 | anisotropic: False 24 | reduction: 'max' 25 | group_args: 26 | NAME: 'ballquery' 27 | use_xyz: True 28 | normalize_dp: False 29 | conv_args: 30 | order: conv-norm-act 31 | act_args: 32 | act: 'relu' 33 | norm_args: 34 | norm: 'bn' 35 | cls_args: 36 | NAME: ClsHead 37 | num_classes: 15 38 | mlps: [512, 256] 39 | norm_args: 40 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/pointnet.yaml: -------------------------------------------------------------------------------- 1 | # GFLOPs GMACs Params.(M) 2 | # 0.91 0.45 3.473 3 | # Throughput (ins./s):4212.155113370464 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: PointNetEncoder 9 | in_channels: 4 10 | cls_args: 11 | NAME: ClsHead 12 | num_classes: 15 13 | in_channels: 1024 14 | mlps: [512,256] 15 | norm_args: 16 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | # FLOPs GMACs Params.(M) 2 | # 1.64 0.81 1.367 3 | # 2040.039810480711 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: PointNextEncoder 9 | blocks: [1, 1, 1, 1, 1, 1] 10 | strides: [1, 2, 2, 2, 2, 1] 11 | width: 32 12 | in_channels: 4 13 | sa_layers: 2 14 | sa_use_res: True 15 | radius: 0.15 16 | radius_scaling: 1.5 17 | nsample: 32 18 | expansion: 4 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | cls_args: 32 | NAME: ClsHead 33 | num_classes: 15 34 | mlps: [512, 256] 35 | norm_args: 36 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn_pix4point/default.yaml: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- # 2 | # Dataset cfgs 3 | # ---------------------------------------------------------------------------- # 4 | dataset: 5 | common: 6 | NAME: ScanObjectNNHardest 7 | data_dir: './data/ScanObjectNN/h5_files/main_split' 8 | train: 9 | split: train 10 | val: 11 | split: val 12 | num_points: 1024 13 | 14 | num_points: 1024 # the number of points passed into model 15 | num_classes: &nclass 16 | 15 17 | 18 | feature_keys: pos 19 | 20 | datatransforms: 21 | train: [PointsToTensor, PointCloudScaling, PointCloudCenterAndNormalize, PointCloudRotation] 22 | vote: [PointCloudRotation] 23 | val: [PointsToTensor, PointCloudCenterAndNormalize] 24 | kwargs: 25 | scale: [0.9, 1.1] 26 | angle: [0.0, 1.0, 0.0] 27 | gravity_dim: 1 28 | normalize: False 29 | 30 | batch_size: 32 31 | val_batch_size: 64 32 | dataloader: 33 | num_workers: 6 34 | 35 | # ---------------------------------------------------------------------------- # 36 | # Training cfgs 37 | # ---------------------------------------------------------------------------- # 38 | criterion_args: 39 | NAME: CrossEntropy 40 | label_smoothing: 0.0 41 | 42 | lr: 5.0e-4 43 | optimizer: 44 | NAME: 'adamw' 45 | weight_decay: 0.05 46 | 47 | sched: cosine 48 | epochs: 300 49 | warmup_epochs: 10 50 | min_lr: 1.0e-6 51 | grad_norm_clip: 10 52 | 53 | # ---------------------------------------------------------------------------- # 54 | # io and misc 55 | # ---------------------------------------------------------------------------- # 56 | print_freq: 10 57 | val_freq: 1 58 | # ----------------- Model related 59 | log_dir: log/scanobject/pix4point 60 | wandb: 61 | project: pix4point-ScanObjectNN 62 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/scanobjectnn_pix4point/pix4point.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BaseCls 3 | encoder_args: 4 | NAME: PointViT 5 | in_channels: 3 6 | embed_dim: 384 7 | depth: 12 8 | num_heads: 6 9 | mlp_ratio: 4. 10 | drop_rate: 0. 11 | attn_drop_rate: 0.1 12 | drop_path_rate: 0.0 13 | qkv_bias: True 14 | act_args: 15 | act: 'gelu' 16 | norm_args: 17 | norm: 'ln' 18 | eps: 1.0e-6 19 | embed_args: 20 | NAME: P3Embed 21 | feature_type: 'dp_df' 22 | reduction: 'max' 23 | sample_ratio: 0.25 24 | normalize_dp: False 25 | group_size: 32 26 | subsample: 'fps' 27 | group: 'knn' 28 | norm_args: bn 29 | conv_args: 30 | order: conv-norm-act 31 | layers: 4 32 | global_feat: max,cls 33 | cls_args: 34 | NAME: ClsHead 35 | num_classes: 15 36 | mlps: [256, 256] 37 | norm_args: 38 | norm: 'bn1d' 39 | 40 | pretrained_path: pretrained/imagenet/mae_s.pth 41 | mode: finetune_encoder 42 | 43 | # ---------------------------------------------------------------------------- # 44 | # Dataset cfgs 45 | # ---------------------------------------------------------------------------- # 46 | # 1. we center the point cloud to eschew from learning translation invariant. 47 | # 2. we added rotation augmentation 48 | datatransforms: 49 | train: [PointsToTensor, PointCloudScaling, PointCloudCenterAndNormalize, PointCloudRotation] 50 | vote: [PointCloudRotation] 51 | val: [PointsToTensor, PointCloudCenterAndNormalize] 52 | kwargs: 53 | scale: [0.9, 1.1] 54 | angle: [0.0, 1.0, 0.0] 55 | gravity_dim: 1 56 | normalize: False 57 | # ---------------------------------------------------------------------------- # 58 | # Training cfgs, same as PointMAE for fair comparasion 59 | # ---------------------------------------------------------------------------- # 60 | # scheduler 61 | criterion_args: 62 | NAME: CrossEntropy 63 | label_smoothing: 0.0 64 | 65 | # Optimizer 66 | lr: 5.0e-4 67 | optimizer: 68 | NAME: 'adamw' 69 | weight_decay: 0.05 70 | 71 | sched: cosine 72 | epochs: 300 73 | t_max: 300 74 | warmup_epochs: 10 75 | min_lr: 1.0e-6 76 | grad_norm_clip: 10 77 | 78 | log_dir: log/scanobject/pix4point 79 | wandb: 80 | project: pix4point-ScanObjectNN 81 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart/default.yaml: -------------------------------------------------------------------------------- 1 | dataset: 2 | common: 3 | NAME: ShapeNetPartNormal 4 | data_root: data/ShapeNetPart/shapenetcore_partanno_segmentation_benchmark_v0_normal 5 | use_normal: True 6 | num_points: 2048 7 | train: 8 | split: trainval 9 | val: 10 | split: test 11 | presample: True 12 | 13 | num_classes: 50 14 | shape_classes: 16 15 | num_points: 2048 16 | normal_channel: True 17 | feature_keys: pos,x,heights 18 | 19 | datatransforms: 20 | train: [PointsToTensor, PointCloudScaling,PointCloudCenterAndNormalize,PointCloudJitter,ChromaticDropGPU] 21 | val: [PointsToTensor, PointCloudCenterAndNormalize] 22 | vote: [PointCloudScaling] 23 | kwargs: 24 | jitter_sigma: 0.001 25 | jitter_clip: 0.005 26 | scale: [0.8, 1.2] 27 | gravity_dim: 1 28 | angle: [0, 1.0, 0] 29 | 30 | batch_size: 8 31 | dataloader: 32 | num_workers: 6 33 | 34 | # ---------------------------------------------------------------------------- # 35 | # Evaluation cfgs 36 | # ---------------------------------------------------------------------------- # 37 | num_votes: 10 38 | refine: True 39 | 40 | # ---------------------------------------------------------------------------- # 41 | # Training cfgs 42 | # ---------------------------------------------------------------------------- # 43 | 44 | # lr_scheduler: 45 | lr: 0.001 46 | min_lr: null 47 | optimizer: 48 | NAME: adamw 49 | weight_decay: 1.0e-4 # the best 50 | 51 | criterion_args: 52 | NAME: Poly1FocalLoss 53 | 54 | # scheduler 55 | epochs: 300 56 | sched: multistep 57 | decay_epochs: [210, 270] 58 | decay_rate: 0.1 59 | warmup_epochs: 0 60 | 61 | 62 | sched_on_epoch: True 63 | 64 | grad_norm_clip: 1 65 | use_voting: False 66 | 67 | # ---------------------------------------------------------------------------- # 68 | # io and misc 69 | # ---------------------------------------------------------------------------- # 70 | print_freq: 10 71 | val_freq: 1 72 | 73 | # ----------------- Model related 74 | pretrained_path: null 75 | 76 | wandb: 77 | project: PointNext-ShapeNetPart -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | # ===>loading from cfgs/shapenetpart/pointnext-s.yaml 2 | # Number of params: 0.9817 M 3 | # test input size: ((torch.Size([1, 2048, 3]), torch.Size([1, 3, 2048]))) 4 | # Batches npoints Params.(M) GFLOPs 5 | # 64 2048 0.982 4.52 6 | model: 7 | NAME: BasePartSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [ 1, 1, 1, 1, 1 ] # 1, 1, 1, 2, 1 is better, but not the main focus of this paper 11 | strides: [ 1, 2, 2, 2, 2 ] 12 | width: 32 13 | in_channels: 7 # better than 4,6 14 | sa_layers: 3 # better than 2 15 | sa_use_res: True 16 | radius: 0.1 17 | radius_scaling: 2.5 18 | nsample: 32 # will not improve performance. 19 | expansion: 4 20 | aggr_args: 21 | feature_type: 'dp_fj' 22 | reduction: 'max' 23 | group_args: 24 | NAME: 'ballquery' 25 | normalize_dp: True 26 | conv_args: 27 | order: conv-norm-act 28 | act_args: 29 | act: 'relu' # leakrelu makes training unstable. 30 | norm_args: 31 | norm: 'bn' # ln makes training unstable 32 | decoder_args: 33 | NAME: PointNextPartDecoder 34 | cls_map: curvenet 35 | cls_args: 36 | NAME: SegHead 37 | global_feat: max,avg # apped global feature to each point feature 38 | num_classes: 50 39 | in_channels: null 40 | norm_args: 41 | norm: 'bn' 42 | 43 | 44 | # ---------------------------------------------------------------------------- # 45 | # Training cfgs 46 | # ---------------------------------------------------------------------------- # 47 | lr: 0.001 48 | min_lr: null 49 | optimizer: 50 | NAME: adamw 51 | weight_decay: 1.0e-4 # the best 52 | 53 | criterion_args: 54 | NAME: Poly1FocalLoss 55 | 56 | # scheduler 57 | epochs: 300 58 | sched: multistep 59 | decay_epochs: [210, 270] 60 | decay_rate: 0.1 61 | warmup_epochs: 0 62 | 63 | datatransforms: 64 | train: [PointsToTensor, PointCloudScaling,PointCloudCenterAndNormalize,PointCloudJitter,ChromaticDropGPU] 65 | val: [PointsToTensor, PointCloudCenterAndNormalize] 66 | kwargs: 67 | jitter_sigma: 0.001 68 | jitter_clip: 0.005 69 | scale: [0.8, 1.2] 70 | gravity_dim: 1 71 | angle: [0, 1.0, 0] -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart/pointnext-s_c160.yaml: -------------------------------------------------------------------------------- 1 | # CUDA_VISIBLE_DEVICES=0 python examples/profile.py --cfg cfgs/shapenetpart/pointnext-s_c160.yaml batch_size=64 num_points=2048 timing=True flops=True 2 | # ------------ 3 | # ===>loading from cfgs/shapenetpart/pointnext-s_c160.yaml 4 | # Number of params: 22.4999 M 5 | # test input size: ((torch.Size([1, 2048, 3]), torch.Size([1, 3, 2048]))) 6 | # Batches npoints Params.(M) GFLOPs 7 | # 64 2048 22.500 110.18 8 | # Throughput (ins./s): 76.0178306799044 9 | 10 | model: 11 | NAME: BasePartSeg 12 | encoder_args: 13 | NAME: PointNextEncoder 14 | blocks: [ 1, 1, 1, 1, 1 ] # 1, 1, 1, 2, 1 is better, but not the main focus of this paper 15 | strides: [ 1, 2, 2, 2, 2 ] 16 | width: 160 17 | in_channels: 7 # better than 4,6 18 | sa_layers: 3 # better than 2 19 | sa_use_res: True 20 | radius: 0.1 21 | radius_scaling: 2.5 22 | nsample: 32 # will not improve performance. 23 | expansion: 4 24 | aggr_args: 25 | feature_type: 'dp_fj' 26 | reduction: 'max' 27 | group_args: 28 | NAME: 'ballquery' 29 | normalize_dp: True 30 | conv_args: 31 | order: conv-norm-act 32 | act_args: 33 | act: 'relu' # leakrelu makes training unstable. 34 | norm_args: 35 | norm: 'bn' # ln makes training unstable 36 | decoder_args: 37 | NAME: PointNextPartDecoder 38 | cls_map: curvenet 39 | cls_args: 40 | NAME: SegHead 41 | global_feat: max,avg # append global feature to each point feature 42 | num_classes: 50 43 | in_channels: null 44 | norm_args: 45 | norm: 'bn' 46 | 47 | 48 | # ---------------------------------------------------------------------------- # 49 | # Training cfgs 50 | # ---------------------------------------------------------------------------- # 51 | lr: 0.001 52 | min_lr: null 53 | optimizer: 54 | NAME: adamw 55 | weight_decay: 1.0e-4 # the best 56 | 57 | criterion_args: 58 | NAME: Poly1FocalLoss 59 | 60 | # scheduler 61 | epochs: 300 62 | sched: multistep 63 | decay_epochs: [210, 270] 64 | decay_rate: 0.1 65 | warmup_epochs: 0 66 | 67 | datatransforms: 68 | train: [PointsToTensor, PointCloudScaling,PointCloudCenterAndNormalize,PointCloudJitter,ChromaticDropGPU] 69 | val: [PointsToTensor, PointCloudCenterAndNormalize] 70 | kwargs: 71 | jitter_sigma: 0.001 72 | jitter_clip: 0.005 73 | scale: [0.8, 1.2] 74 | gravity_dim: 1 75 | angle: [0, 1.0, 0] 76 | 77 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart/pointnext-s_c64.yaml: -------------------------------------------------------------------------------- 1 | # CUDA_VISIBLE_DEVICES=0 python examples/profile.py --cfg cfgs/shapenetpart/pointnext-s_c64.yaml batch_size=64 num_points=2048 timing=True flops=True 2 | # Batches npoints Params.(M) GFLOPs 3 | # 64 2048 3.722 17.80 4 | # Throughput (ins./s): 330.9890643832901 5 | 6 | model: 7 | NAME: BasePartSeg 8 | encoder_args: 9 | NAME: PointNextEncoder 10 | blocks: [ 1, 1, 1, 1, 1 ] # 1, 1, 1, 2, 1 is better, but not the main focus of this paper 11 | strides: [ 1, 2, 2, 2, 2 ] 12 | width: 64 13 | in_channels: 7 # better than 4,6 14 | sa_layers: 3 # better than 2 15 | sa_use_res: True 16 | radius: 0.1 17 | radius_scaling: 2.5 18 | nsample: 32 # will not improve performance. 19 | expansion: 4 20 | aggr_args: 21 | feature_type: 'dp_fj' 22 | reduction: 'max' 23 | group_args: 24 | NAME: 'ballquery' 25 | normalize_dp: True 26 | conv_args: 27 | order: conv-norm-act 28 | act_args: 29 | act: 'relu' # leakrelu makes training unstable. 30 | norm_args: 31 | norm: 'bn' # ln makes training unstable 32 | decoder_args: 33 | NAME: PointNextPartDecoder 34 | cls_map: curvenet 35 | cls_args: 36 | NAME: SegHead 37 | global_feat: max,avg # append global feature to each point feature 38 | num_classes: 50 39 | in_channels: null 40 | norm_args: 41 | norm: 'bn' 42 | 43 | # ---------------------------------------------------------------------------- # 44 | # Training cfgs 45 | # ---------------------------------------------------------------------------- # 46 | lr: 0.001 47 | min_lr: null 48 | optimizer: 49 | NAME: adamw 50 | weight_decay: 1.0e-4 # the best 51 | 52 | criterion_args: 53 | NAME: Poly1FocalLoss 54 | 55 | # scheduler 56 | epochs: 300 57 | sched: multistep 58 | decay_epochs: [210, 270] 59 | decay_rate: 0.1 60 | warmup_epochs: 0 61 | 62 | datatransforms: 63 | train: [PointsToTensor, PointCloudScaling,PointCloudCenterAndNormalize,PointCloudJitter,ChromaticDropGPU] 64 | val: [PointsToTensor, PointCloudCenterAndNormalize] 65 | kwargs: 66 | jitter_sigma: 0.001 67 | jitter_clip: 0.005 68 | scale: [0.8, 1.2] 69 | gravity_dim: 1 70 | angle: [0, 1.0, 0] -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart_pix4point/default.yaml: -------------------------------------------------------------------------------- 1 | dataset: 2 | common: 3 | NAME: ShapeNetPartNormal 4 | data_root: data/ShapeNetPart/shapenetcore_partanno_segmentation_benchmark_v0_normal 5 | use_normal: True 6 | num_points: 2048 7 | train: 8 | split: trainval 9 | val: 10 | split: test 11 | presample: True 12 | 13 | num_classes: 50 14 | shape_classes: 16 15 | num_points: 2048 16 | normal_channel: True 17 | feature_keys: pos,x,heights 18 | 19 | datatransforms: 20 | train: [PointsToTensor, PointCloudScaling,PointCloudCenterAndNormalize,PointCloudJitter,ChromaticDropGPU] 21 | val: [PointsToTensor, PointCloudCenterAndNormalize ] 22 | vote: [PointCloudScaling] 23 | kwargs: 24 | jitter_sigma: 0.001 25 | jitter_clip: 0.005 26 | scale: [0.8, 1.2] 27 | gravity_dim: 1 28 | angle: [0, 1.0, 0] 29 | 30 | batch_size: 8 31 | dataloader: 32 | num_workers: 6 33 | 34 | # ---------------------------------------------------------------------------- # 35 | # Evaluation cfgs 36 | # ---------------------------------------------------------------------------- # 37 | num_votes: 10 38 | refine: True 39 | 40 | # ---------------------------------------------------------------------------- # 41 | # Training cfgs 42 | # ---------------------------------------------------------------------------- # 43 | lr: 5.0e-4 # LR # best 44 | # min_lr: 1.0e-6 45 | optimizer: 46 | NAME: adamw 47 | weight_decay: 1.0e-4 48 | 49 | criterion_args: 50 | NAME: Poly1FocalLoss 51 | 52 | # scheduler 53 | epochs: 300 54 | sched: multistep 55 | decay_epochs: [210, 270] 56 | decay_rate: 0.1 57 | warmup_epochs: 0 58 | 59 | sched_on_epoch: True 60 | 61 | grad_norm_clip: 1 62 | use_voting: False 63 | # ---------------------------------------------------------------------------- # 64 | # io and misc 65 | # ---------------------------------------------------------------------------- # 66 | print_freq: 10 67 | val_freq: 1 68 | 69 | # ----------------- Model related 70 | pretrained_path: null 71 | 72 | wandb: 73 | project: pix4point-ShapeNetPart 74 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/cfgs/shapenetpart_pix4point/pix4point.yaml: -------------------------------------------------------------------------------- 1 | model: 2 | NAME: BasePartSeg 3 | encoder_args: 4 | NAME: PointViT 5 | in_channels: 7 6 | embed_dim: 384 7 | depth: 12 8 | num_heads: 6 9 | mlp_ratio: 4. 10 | drop_rate: 0. 11 | attn_drop_rate: 0.0 12 | drop_path_rate: 0.1 13 | add_pos_each_block: True 14 | qkv_bias: True 15 | act_args: 16 | act: 'gelu' 17 | norm_args: 18 | norm: 'ln' 19 | eps: 1.0e-6 20 | embed_args: 21 | NAME: P3Embed 22 | feature_type: 'dp_df' 23 | reduction: 'max' 24 | sample_ratio: 0.0625 25 | normalize_dp: False 26 | group_size: 32 27 | subsample: 'fps' # random, FPS 28 | group: 'knn' # change it to group args. 29 | conv_args: 30 | order: conv-norm-act 31 | layers: 4 32 | norm_args: 33 | norm: 'bn' 34 | decoder_args: 35 | NAME: PointViTPartDecoder 36 | channel_scaling: 1 37 | global_feat: cls,max,avg 38 | progressive_input: True 39 | cls_args: 40 | NAME: SegHead 41 | num_classes: 50 42 | mlps: [256] 43 | in_channels: null 44 | norm_args: 45 | norm: 'bn' 46 | 47 | mode: finetune_encoder 48 | pretrained_path: pretrained/imagenet/mae_s.pth 49 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/changes.md: -------------------------------------------------------------------------------- 1 | # Change Logs & TODOs 2 | 3 | 4 | ## Change Logs 5 | - [2022/08/21] Added ShapeNetPart and ScanNet. Support AMP. 6 | - [2022/07/09] Initial Realse 7 | 8 | 9 | ## TODO 10 | - [ ] clean segmentation 11 | - [ ] support multi-gpu testing for segmentation tasks -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/examples/modelnet.md: -------------------------------------------------------------------------------- 1 | # Point cloud classification on ModelNet40 2 | 3 | Note in this experiment, we do not use any re-sampled version of ModelNet40 (more than 2K points) or any normal information. The data we use is: `modelnet40_ply_hdf5_2048`[1]. 4 | 5 | ## Dataset 6 | ModelNet40 dataset will be downloaded automatically. 7 | 8 | 9 | ## Train 10 | For example, train `PointNeXt-S` 11 | ```bash 12 | CUDA_VISIBLE_DEVICES=0 python examples/classification/main.py --cfg cfgs/modelnet40ply2048/pointnext-s.yaml 13 | ``` 14 | 15 | ## Test 16 | 17 | test `PointNeXt-S (C=64)` 18 | 19 | ```bash 20 | CUDA_VISIBLE_DEVICES=0 python examples/classification/main.py --cfg cfgs/modelnet40ply2048/pointnext-s.yaml model.encoder_args.width=64 mode=test --pretrained_path /path/to/your/pretrained_model 21 | ``` 22 | 23 | ## Reference 24 | ``` 25 | @InProceedings{wu2015modelnet, 26 | author = {Wu, Zhirong and Song, Shuran and Khosla, Aditya and Yu, Fisher and Zhang, Linguang and Tang, Xiaoou and Xiao, Jianxiong}, 27 | title = {3D ShapeNets: A Deep Representation for Volumetric Shapes}, 28 | booktitle = {CVPR}, 29 | year = {2015} 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/examples/scannet.md: -------------------------------------------------------------------------------- 1 | # Large-Scale 3D Segmentation on ScanNet 2 | 3 | 4 | ## Dataset 5 | 6 | 7 | You can download our preprocessed ScanNet dataset as follows: 8 | ```bash 9 | cd data 10 | gdown https://drive.google.com/uc?id=1uWlRPLXocqVbJxPvA2vcdQINaZzXf1z_ 11 | tar -xvf ScanNet.tar 12 | ``` 13 | Please cite the ScanNet paper [1] if you are going to conduct experiments on it. 14 | 15 | 16 | 17 | ## Train 18 | 19 | For example, train `PointNext-XL` using 8 GPUs by default. 20 | ```bash 21 | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python examples/segmentation/main.py --cfg cfgs/scannet/pointnext-xl.yaml 22 | ``` 23 | * change the cfg file to use any other model, *e.g.* `cfgs/s3dis/pointnet++.yaml` for training PointNet++ 24 | * run the command at the root directory 25 | 26 | 27 | ## Val 28 | 29 | ```bash 30 | CUDA_VISIBLE_DEVICES=0 python examples/segmentation/main.py --cfg cfgs/scannet/ mode=test dataset.test.split=val --pretrained_path 31 | ``` 32 | 33 | ## Test 34 | 35 | You can generate Scannet benchmark submission file as follows 36 | ```bash 37 | CUDA_VISIBLE_DEVICES=0 python examples/segmentation/main.py --cfg cfgs/scannet/ mode=test dataset.test.split=test no_label=True pretrained_path= 38 | ``` 39 | Please make sure your checkpoint and your cfg matches with each. 40 | 41 | 42 | ## Reference 43 | 44 | ``` 45 | @inproceedings{dai2017scannet, 46 | title={{ScanNet}: Richly-annotated {3D} Reconstructions of Indoor Scenes}, 47 | author={Dai, Angela and Chang, Angel X. and Savva, Manolis and Halber, Maciej and Funkhouser, Thomas and Nie{\ss}ner, Matthias}, 48 | booktitle = CVPR, 49 | year = {2017} 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/misc/wandb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/misc/wandb.png -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/projects/misc/effects_training_scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/projects/misc/effects_training_scaling.png -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/projects/misc/pix4point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/projects/misc/pix4point.png -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/projects/misc/pointnext.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/projects/misc/pointnext.jpeg -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/projects/misc/s3dis_vis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/projects/misc/s3dis_vis.png -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/docs/projects/misc/shapenetpart_vis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/docs/projects/misc/shapenetpart_vis.png -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/examples/__init__.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '../')) 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/examples/classification/__init__.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')) 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/examples/segmentation/__init__.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')) 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/examples/segmentation/vis_results.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | import __init__ 4 | import os 5 | from openpoints.dataset.vis3d import read_obj, vis_multi_points 6 | 7 | 8 | # -------------------------------- 9 | idx = 0 10 | data_dir = "pretrained/pix4point/mae-s/visualization" 11 | dataset_name = 's3dissphere' 12 | roof_height = 3 13 | # -------------------------------- 14 | 15 | method_names = ['input', 'pix4point', 'gt'] 16 | file_list = [] 17 | colors_list = [] 18 | for i, method_name in enumerate(method_names): 19 | file_path = os.path.join(data_dir, f'{method_name}-{dataset_name}-{idx}.obj') 20 | points, colors =read_obj(file_path) 21 | if i == 0: # input 22 | # remove roof 23 | valid_idx = points[:, 2] < roof_height 24 | input_points = points[valid_idx] 25 | colors_list.append(colors[valid_idx]/255.) 26 | else: 27 | colors_list.append(colors[valid_idx]) 28 | 29 | points_list = [input_points] * len(method_names) 30 | vis_multi_points(points_list, colors_list) -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/examples/shapenetpart/__init__.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')) 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # command to install this enviroment: source init.sh 3 | 4 | # install miniconda3 if not installed yet. 5 | #wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 6 | #bash Miniconda3-latest-Linux-x86_64.sh 7 | #source ~/.bashrc 8 | 9 | 10 | # The following 4 lines are only for slurm machines. uncomment if needed. 11 | # export TORCH_CUDA_ARCH_LIST="6.1;6.2;7.0;7.5;8.0" # a100: 8.0; v100: 7.0; 2080ti: 7.5; titan xp: 6.1 12 | # module purge 13 | # module load cuda/11.3.1 14 | # module load gcc/7.5.0 15 | 16 | # download openpoints 17 | # git submodule add git@github.com:guochengqian/openpoints.git 18 | git submodule update --init --recursive 19 | git submodule update --remote --merge # update to the latest version 20 | 21 | # install PyTorch 22 | #conda deactivate 23 | #conda env remove --name openpoints 24 | #conda create -n openpoints -y python=3.7 numpy=1.20 numba 25 | #conda activate openpoints 26 | 27 | # please always double check installation for pytorch and torch-scatter from the official documentation 28 | conda install -y pytorch=1.10.1 torchvision cudatoolkit=11.3 -c pytorch -c nvidia 29 | pip install torch-scatter -f https://data.pyg.org/whl/torch-1.10.1+cu113.html 30 | 31 | pip install -r requirements.txt 32 | 33 | # install cpp extensions, the pointnet++ library 34 | cd openpoints/cpp/pointnet2_batch 35 | python setup.py install 36 | cd ../ 37 | 38 | # grid_subsampling library. necessary only if interested in S3DIS_sphere 39 | cd subsampling 40 | python setup.py build_ext --inplace 41 | cd .. 42 | 43 | 44 | # # point transformer library. Necessary only if interested in Point Transformer and Stratified Transformer 45 | cd pointops/ 46 | python setup.py install 47 | cd .. 48 | 49 | # Blow are functions that optional. Necessary only if interested in reconstruction tasks such as completion 50 | cd chamfer_dist 51 | python setup.py install --user 52 | cd ../emd 53 | python setup.py install --user 54 | cd ../../../ 55 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: 'OpenPoints' 2 | site_description: 'Library for PointNeXt, ASSANet, Pix4Point, and other point-based methods' 3 | repo_name: 'guochengqian/pointnext' 4 | repo_url: 'https://github.com/guochengqian/pointnext' 5 | nav: 6 | - index.md 7 | - Examples: 8 | - examples/scanobjectnn.md 9 | - examples/modelnet.md 10 | - examples/shapenetpart.md 11 | - examples/s3dis.md 12 | - examples/scannet.md 13 | - ... | projects/*.md 14 | - modelzoo.md 15 | - changes.md 16 | theme: 17 | name: 'material' 18 | feature: 19 | tabs: false 20 | extra_javascript: 21 | - 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML' 22 | - https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js 23 | - javascripts/tables.js 24 | markdown_extensions: 25 | - codehilite: 26 | linenums: true 27 | - admonition 28 | - pymdownx.arithmatex 29 | - pymdownx.betterem: 30 | smart_enable: all 31 | - pymdownx.caret 32 | - pymdownx.critic 33 | - pymdownx.details 34 | - pymdownx.emoji: 35 | emoji_generator: !!python/name:pymdownx.emoji.to_svg 36 | - pymdownx.inlinehilite 37 | - pymdownx.magiclink 38 | - pymdownx.mark 39 | - pymdownx.smartsymbols 40 | - pymdownx.superfences 41 | - pymdownx.tasklist: 42 | custom_checkbox: true 43 | - pymdownx.tilde 44 | - mdx_truly_sane_lists 45 | plugins: 46 | - search 47 | - awesome-pages 48 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/README.md: -------------------------------------------------------------------------------- 1 | # OpenPoints 2 | 3 | OpenPoints is a library built for fairly benchmarking and easily reproducing point-based methods for point cloud understanding. It is born in the course of [PointNeXt](https://github.com/guochengqian/PointNeXt) project and is used as an engine therein. 4 | 5 | **For any question related to OpenPoints, please open an issue in [PointNeXt](https://github.com/guochengqian/PointNeXt) repo.** 6 | 7 | OpenPoints currently supports reproducing the following models: 8 | - PointNet 9 | - DGCNN 10 | - DeepGCN 11 | - PointNet++ 12 | - ASSANet 13 | - PointMLP 14 | - PointNeXt 15 | - Pix4Point 16 | 17 | 18 | 19 | ## Features 20 | 21 | 1. **Extensibility**: supports many representative networks for point cloud understanding, such as *PointNet, DGCNN, DeepGCN, PointNet++, ASSANet, PointMLP*, and our ***PointNeXt***. More networks can be built easily based on our framework since **OpenPoints support a wide range of basic operations including graph convolutions, self-attention, farthest point sampling, ball query, *e.t.c***. 22 | 23 | 2. **Ease of Use**: *Build* model, optimizer, scheduler, loss function, and data loader *easily from cfg*. Train and validate different models on various tasks by simply changing the `cfg\*\*.yaml` file. 24 | 25 | ``` 26 | model = build_model_from_cfg(cfg.model) 27 | criterion = build_criterion_from_cfg(cfg.criterion_args) 28 | ``` 29 | 30 | 31 | 32 | ## Usage 33 | 34 | OpenPoints only serves as an engine. Please refer to [PointNeXt](https://github.com/guochengqian/PointNeXt) for a specific example of how to use and install 35 | 36 | 37 | 38 | ## Citation 39 | 40 | If you use this library, please kindly acknowledge our work: 41 | ```tex 42 | @Article{qian2022pointnext, 43 | author = {Qian, Guocheng and Li, Yuchen and Peng, Houwen and Mai, Jinjie and Hammoud, Hasan and Elhoseiny, Mohamed and Ghanem, Bernard}, 44 | title = {PointNeXt: Revisiting PointNet++ with Improved Training and Scaling Strategies}, 45 | journal = {arXiv:2206.04670}, 46 | year = {2022}, 47 | } 48 | ``` 49 | 50 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/__init__.py: -------------------------------------------------------------------------------- 1 | from .transforms import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | 6 | from .pointnet2_batch import pointnet2_cuda -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/chamfer_dist/chamfer_cuda.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Haozhe Xie 3 | * @Date: 2019-08-07 20:54:24 4 | * @Last Modified by: Haozhe Xie 5 | * @Last Modified time: 2019-12-10 10:33:50 6 | * @Email: cshzxie@gmail.com 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | std::vector chamfer_cuda_forward(torch::Tensor xyz1, 13 | torch::Tensor xyz2); 14 | 15 | std::vector chamfer_cuda_backward(torch::Tensor xyz1, 16 | torch::Tensor xyz2, 17 | torch::Tensor idx1, 18 | torch::Tensor idx2, 19 | torch::Tensor grad_dist1, 20 | torch::Tensor grad_dist2); 21 | 22 | std::vector chamfer_forward(torch::Tensor xyz1, 23 | torch::Tensor xyz2) { 24 | return chamfer_cuda_forward(xyz1, xyz2); 25 | } 26 | 27 | std::vector chamfer_backward(torch::Tensor xyz1, 28 | torch::Tensor xyz2, 29 | torch::Tensor idx1, 30 | torch::Tensor idx2, 31 | torch::Tensor grad_dist1, 32 | torch::Tensor grad_dist2) { 33 | return chamfer_cuda_backward(xyz1, xyz2, idx1, idx2, grad_dist1, grad_dist2); 34 | } 35 | 36 | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { 37 | m.def("forward", &chamfer_forward, "Chamfer forward (CUDA)"); 38 | m.def("backward", &chamfer_backward, "Chamfer backward (CUDA)"); 39 | } 40 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/chamfer_dist/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: Haozhe Xie 3 | # @Date: 2019-08-07 20:54:24 4 | # @Last Modified by: Haozhe Xie 5 | # @Last Modified time: 2019-12-10 10:04:25 6 | # @Email: cshzxie@gmail.com 7 | 8 | from setuptools import setup 9 | from torch.utils.cpp_extension import BuildExtension, CUDAExtension 10 | 11 | setup(name='chamfer', 12 | version='2.0.0', 13 | ext_modules=[ 14 | CUDAExtension('chamfer', [ 15 | 'chamfer_cuda.cpp', 16 | 'chamfer.cu', 17 | ]), 18 | ], 19 | cmdclass={'build_ext': BuildExtension}) 20 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/chamfer_dist/test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: Haozhe Xie 3 | # @Date: 2019-12-10 10:38:01 4 | # @Last Modified by: Haozhe Xie 5 | # @Last Modified time: 2019-12-26 14:21:36 6 | # @Email: cshzxie@gmail.com 7 | # 8 | # Note: 9 | # - Replace float -> double, kFloat -> kDouble in chamfer.cu 10 | 11 | import os 12 | import sys 13 | import torch 14 | import unittest 15 | 16 | from torch.autograd import gradcheck 17 | 18 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))) 19 | from openpoints.cpp.chamfer_dist import ChamferFunction 20 | 21 | 22 | class ChamferDistanceTestCase(unittest.TestCase): 23 | def test_chamfer_dist(self): 24 | x = torch.rand(4, 64, 3).float() 25 | y = torch.rand(4, 128, 3).float() 26 | x.requires_grad = True 27 | y.requires_grad = True 28 | print(gradcheck(ChamferFunction.apply, [x.cuda(), y.cuda()])) 29 | 30 | 31 | if __name__ == '__main__': 32 | x = torch.rand(32, 128, 3) 33 | y = torch.rand(32, 128, 3) 34 | # print() 35 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | build 3 | dist 4 | emd_ext.egg-info 5 | *.so 6 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/README.md: -------------------------------------------------------------------------------- 1 | # PyTorch Wrapper for Point-cloud Earth-Mover-Distance (EMD) 2 | 3 | ## Dependency 4 | 5 | The code has been tested on Ubuntu 16.04, PyTorch 1.1.0, CUDA 9.0. 6 | 7 | ## Usage 8 | 9 | First compile using 10 | 11 | python setup.py install 12 | 13 | Then, copy the lib file out to the main directory, 14 | 15 | cp build/lib.linux-x86_64-3.6/emd_cuda.cpython-36m-x86_64-linux-gnu.so . 16 | 17 | Then, you can use it by simply 18 | 19 | from emd import earth_mover_distance 20 | d = earth_mover_distance(p1, p2, transpose=False) # p1: B x N1 x 3, p2: B x N2 x 3 21 | 22 | Check `test_emd_loss.py` for example. 23 | 24 | ## Author 25 | 26 | The cuda code is originally written by Haoqiang Fan. The PyTorch wrapper is written by Kaichun Mo. Also, Jiayuan Gu provided helps. 27 | 28 | ## License 29 | 30 | MIT 31 | 32 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/__init__.py: -------------------------------------------------------------------------------- 1 | from .emd import earth_mover_distance as emd 2 | 3 | __all__ = ['emd'] -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/cuda/emd.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _EMD 2 | #define _EMD 3 | 4 | #include 5 | #include 6 | 7 | //CUDA declarations 8 | at::Tensor ApproxMatchForward( 9 | const at::Tensor xyz1, 10 | const at::Tensor xyz2); 11 | 12 | at::Tensor MatchCostForward( 13 | const at::Tensor xyz1, 14 | const at::Tensor xyz2, 15 | const at::Tensor match); 16 | 17 | std::vector MatchCostBackward( 18 | const at::Tensor grad_cost, 19 | const at::Tensor xyz1, 20 | const at::Tensor xyz2, 21 | const at::Tensor match); 22 | 23 | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { 24 | m.def("approxmatch_forward", &ApproxMatchForward,"ApproxMatch forward (CUDA)"); 25 | m.def("matchcost_forward", &MatchCostForward,"MatchCost forward (CUDA)"); 26 | m.def("matchcost_backward", &MatchCostBackward,"MatchCost backward (CUDA)"); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/emd.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import emd_cuda 3 | 4 | 5 | class EarthMoverDistanceFunction(torch.autograd.Function): 6 | @staticmethod 7 | def forward(ctx, xyz1, xyz2): 8 | xyz1 = xyz1.contiguous() 9 | xyz2 = xyz2.contiguous() 10 | assert xyz1.is_cuda and xyz2.is_cuda, "Only support cuda currently." 11 | match = emd_cuda.approxmatch_forward(xyz1, xyz2) 12 | cost = emd_cuda.matchcost_forward(xyz1, xyz2, match) 13 | ctx.save_for_backward(xyz1, xyz2, match) 14 | return cost 15 | 16 | @staticmethod 17 | def backward(ctx, grad_cost): 18 | xyz1, xyz2, match = ctx.saved_tensors 19 | grad_cost = grad_cost.contiguous() 20 | grad_xyz1, grad_xyz2 = emd_cuda.matchcost_backward(grad_cost, xyz1, xyz2, match) 21 | return grad_xyz1, grad_xyz2 22 | 23 | 24 | 25 | 26 | class earth_mover_distance(torch.nn.Module): 27 | f''' emd 28 | ''' 29 | def __init__(self): 30 | super().__init__() 31 | 32 | def forward(self, xyz1, xyz2, transpose=False): 33 | """Earth Mover Distance (Approx) 34 | 35 | Args: 36 | xyz1 (torch.Tensor): (b, n1, 3) 37 | xyz2 (torch.Tensor): (b, n2, 3) 38 | transpose (bool): whether to transpose inputs as it might be BCN format. 39 | Extensions only support BNC format. 40 | 41 | Returns: 42 | cost (torch.Tensor): (b) 43 | 44 | """ 45 | 46 | cost = EarthMoverDistanceFunction.apply(xyz1, xyz2) 47 | cost = cost / xyz1.size(1) 48 | 49 | return cost.mean() 50 | # def earth_mover_distance(xyz1, xyz2, transpose=True): 51 | # """Earth Mover Distance (Approx) 52 | 53 | # Args: 54 | # xyz1 (torch.Tensor): (b, 3, n1) 55 | # xyz2 (torch.Tensor): (b, 3, n1) 56 | # transpose (bool): whether to transpose inputs as it might be BCN format. 57 | # Extensions only support BNC format. 58 | 59 | # Returns: 60 | # cost (torch.Tensor): (b) 61 | 62 | # """ 63 | # if xyz1.dim() == 2: 64 | # xyz1 = xyz1.unsqueeze(0) 65 | # if xyz2.dim() == 2: 66 | # xyz2 = xyz2.unsqueeze(0) 67 | # if transpose: 68 | # xyz1 = xyz1.transpose(1, 2) 69 | # xyz2 = xyz2.transpose(1, 2) 70 | # cost = EarthMoverDistanceFunction.apply(xyz1, xyz2) 71 | # return cost 72 | 73 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/setup.py: -------------------------------------------------------------------------------- 1 | """Setup extension 2 | 3 | Notes: 4 | If extra_compile_args is provided, you need to provide different instances for different extensions. 5 | Refer to https://github.com/pytorch/pytorch/issues/20169 6 | 7 | """ 8 | 9 | from setuptools import setup 10 | from torch.utils.cpp_extension import BuildExtension, CUDAExtension 11 | 12 | 13 | setup( 14 | name='emd_ext', 15 | ext_modules=[ 16 | CUDAExtension( 17 | name='emd_cuda', 18 | sources=[ 19 | 'cuda/emd.cpp', 20 | 'cuda/emd_kernel.cu', 21 | ], 22 | extra_compile_args={'cxx': ['-g'], 'nvcc': ['-O2']} 23 | ), 24 | ], 25 | cmdclass={ 26 | 'build_ext': BuildExtension 27 | }) 28 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/emd/test_emd_loss.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy as np 3 | import time 4 | from emd import earth_mover_distance 5 | 6 | # gt 7 | p1 = torch.from_numpy(np.array([[[1.7, -0.1, 0.1], [0.1, 1.2, 0.3]]], dtype=np.float32)).cuda() 8 | p1 = p1.repeat(3, 1, 1) 9 | p2 = torch.from_numpy(np.array([[[0.3, 1.8, 0.2], [1.2, -0.2, 0.3]]], dtype=np.float32)).cuda() 10 | p2 = p2.repeat(3, 1, 1) 11 | print(p1) 12 | print(p2) 13 | print(p1.shape) 14 | p1.requires_grad = True 15 | p2.requires_grad = True 16 | 17 | gt_dist = (((p1[0, 0] - p2[0, 1])**2).sum() + ((p1[0, 1] - p2[0, 0])**2).sum()) / 2 + \ 18 | (((p1[1, 0] - p2[1, 1])**2).sum() + ((p1[1, 1] - p2[1, 0])**2).sum()) * 2 + \ 19 | (((p1[2, 0] - p2[2, 1])**2).sum() + ((p1[2, 1] - p2[2, 0])**2).sum()) / 3 20 | print('gt_dist: ', gt_dist) 21 | 22 | gt_dist.backward() 23 | print(p1.grad) 24 | print(p2.grad) 25 | 26 | # emd 27 | p1 = torch.from_numpy(np.array([[[1.7, -0.1, 0.1], [0.1, 1.2, 0.3]]], dtype=np.float32)).cuda() 28 | p1 = p1.repeat(3, 1, 1) 29 | p2 = torch.from_numpy(np.array([[[0.3, 1.8, 0.2], [1.2, -0.2, 0.3]]], dtype=np.float32)).cuda() 30 | p2 = p2.repeat(3, 1, 1) 31 | print(p1) 32 | print(p2) 33 | p1.requires_grad = True 34 | p2.requires_grad = True 35 | 36 | d = earth_mover_distance(p1, p2, transpose=False) 37 | print(d) 38 | 39 | loss = d[0] / 2 + d[1] * 2 + d[2] / 3 40 | print(loss) 41 | 42 | loss.backward() 43 | print(p1.grad) 44 | print(p2.grad) 45 | 46 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/__init__.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import pointnet2_batch_cuda as pointnet2_cuda 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from torch.utils.cpp_extension import BuildExtension, CUDAExtension 3 | 4 | setup( 5 | name='pointnet2_cuda', 6 | ext_modules=[ 7 | CUDAExtension('pointnet2_batch_cuda', [ 8 | 'src/pointnet2_api.cpp', 9 | 'src/ball_query.cpp', 10 | 'src/ball_query_gpu.cu', 11 | 'src/group_points.cpp', 12 | 'src/group_points_gpu.cu', 13 | 'src/interpolate.cpp', 14 | 'src/interpolate_gpu.cu', 15 | 'src/sampling.cpp', 16 | 'src/sampling_gpu.cu', 17 | ], 18 | extra_compile_args={'cxx': ['-g'], 19 | 'nvcc': ['-O2']}) 20 | ], 21 | cmdclass={'build_ext': BuildExtension} 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/ball_query.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | batch version of ball query, modified from the original implementation of official PointNet++ codes. 3 | Written by Shaoshuai Shi 4 | All Rights Reserved 2018. 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "ball_query_gpu.h" 13 | 14 | #define CHECK_CUDA(x) do { \ 15 | if (!x.type().is_cuda()) { \ 16 | fprintf(stderr, "%s must be CUDA tensor at %s:%d\n", #x, __FILE__, __LINE__); \ 17 | exit(-1); \ 18 | } \ 19 | } while (0) 20 | #define CHECK_CONTIGUOUS(x) do { \ 21 | if (!x.is_contiguous()) { \ 22 | fprintf(stderr, "%s must be contiguous tensor at %s:%d\n", #x, __FILE__, __LINE__); \ 23 | exit(-1); \ 24 | } \ 25 | } while (0) 26 | #define CHECK_INPUT(x) CHECK_CUDA(x);CHECK_CONTIGUOUS(x) 27 | 28 | 29 | int ball_query_wrapper_fast(int b, int n, int m, float radius, int nsample, 30 | at::Tensor new_xyz_tensor, at::Tensor xyz_tensor, at::Tensor idx_tensor) { 31 | CHECK_INPUT(new_xyz_tensor); 32 | CHECK_INPUT(xyz_tensor); 33 | const float *new_xyz = new_xyz_tensor.data(); 34 | const float *xyz = xyz_tensor.data(); 35 | int *idx = idx_tensor.data(); 36 | 37 | ball_query_kernel_launcher_fast(b, n, m, radius, nsample, new_xyz, xyz, idx); 38 | return 1; 39 | } 40 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/ball_query_gpu.cu: -------------------------------------------------------------------------------- 1 | /* 2 | batch version of ball query, modified from the original implementation of official PointNet++ codes. 3 | Written by Shaoshuai Shi 4 | All Rights Reserved 2018. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ball_query_gpu.h" 12 | #include "cuda_utils.h" 13 | 14 | 15 | __global__ void ball_query_kernel_fast(int b, int n, int m, float radius, int nsample, 16 | const float *__restrict__ new_xyz, const float *__restrict__ xyz, int *__restrict__ idx) { 17 | // new_xyz: (B, M, 3) 18 | // xyz: (B, N, 3) 19 | // output: 20 | // idx: (B, M, nsample) 21 | int bs_idx = blockIdx.y; 22 | int pt_idx = blockIdx.x * blockDim.x + threadIdx.x; 23 | if (bs_idx >= b || pt_idx >= m) return; 24 | 25 | new_xyz += bs_idx * m * 3 + pt_idx * 3; 26 | xyz += bs_idx * n * 3; 27 | idx += bs_idx * m * nsample + pt_idx * nsample; 28 | 29 | float radius2 = radius * radius; 30 | float new_x = new_xyz[0]; 31 | float new_y = new_xyz[1]; 32 | float new_z = new_xyz[2]; 33 | 34 | int cnt = 0; 35 | for (int k = 0; k < n; ++k) { 36 | float x = xyz[k * 3 + 0]; 37 | float y = xyz[k * 3 + 1]; 38 | float z = xyz[k * 3 + 2]; 39 | float d2 = (new_x - x) * (new_x - x) + (new_y - y) * (new_y - y) + (new_z - z) * (new_z - z); 40 | if (d2 < radius2){ 41 | if (cnt == 0){ 42 | for (int l = 0; l < nsample; ++l) { 43 | idx[l] = k; 44 | } 45 | } 46 | idx[cnt] = k; 47 | ++cnt; 48 | if (cnt >= nsample) break; 49 | } 50 | } 51 | } 52 | 53 | 54 | void ball_query_kernel_launcher_fast(int b, int n, int m, float radius, int nsample, \ 55 | const float *new_xyz, const float *xyz, int *idx) { 56 | // new_xyz: (B, M, 3) 57 | // xyz: (B, N, 3) 58 | // output: 59 | // idx: (B, M, nsample) 60 | 61 | cudaError_t err; 62 | 63 | dim3 blocks(DIVUP(m, THREADS_PER_BLOCK), b); // blockIdx.x(col), blockIdx.y(row) 64 | dim3 threads(THREADS_PER_BLOCK); 65 | 66 | ball_query_kernel_fast<<>>(b, n, m, radius, nsample, new_xyz, xyz, idx); 67 | // cudaDeviceSynchronize(); // for using printf in kernel function 68 | err = cudaGetLastError(); 69 | if (cudaSuccess != err) { 70 | fprintf(stderr, "CUDA kernel failed : %s\n", cudaGetErrorString(err)); 71 | exit(-1); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/ball_query_gpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _BALL_QUERY_GPU_H 2 | #define _BALL_QUERY_GPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int ball_query_wrapper_fast(int b, int n, int m, float radius, int nsample, 10 | at::Tensor new_xyz_tensor, at::Tensor xyz_tensor, at::Tensor idx_tensor); 11 | 12 | void ball_query_kernel_launcher_fast(int b, int n, int m, float radius, int nsample, 13 | const float *xyz, const float *new_xyz, int *idx); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/cuda_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _CUDA_UTILS_H 2 | #define _CUDA_UTILS_H 3 | 4 | #include 5 | 6 | #define TOTAL_THREADS 1024 7 | #define THREADS_PER_BLOCK 256 8 | #define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0)) 9 | 10 | inline int opt_n_threads(int work_size) { 11 | const int pow_2 = std::log(static_cast(work_size)) / std::log(2.0); 12 | 13 | return max(min(1 << pow_2, TOTAL_THREADS), 1); 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/group_points.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | batch version of point grouping, modified from the original implementation of official PointNet++ codes. 3 | Written by Shaoshuai Shi 4 | All Rights Reserved 2018. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "group_points_gpu.h" 12 | 13 | int group_points_grad_wrapper_fast(int b, int c, int n, int npoints, int nsample, 14 | at::Tensor grad_out_tensor, at::Tensor idx_tensor, at::Tensor grad_points_tensor) 15 | { 16 | 17 | float *grad_points = grad_points_tensor.data(); 18 | const int *idx = idx_tensor.data(); 19 | const float *grad_out = grad_out_tensor.data(); 20 | 21 | group_points_grad_kernel_launcher_fast(b, c, n, npoints, nsample, grad_out, idx, grad_points); 22 | return 1; 23 | } 24 | 25 | int group_points_wrapper_fast(int b, int c, int n, int npoints, int nsample, 26 | at::Tensor points_tensor, at::Tensor idx_tensor, at::Tensor out_tensor) 27 | { 28 | 29 | const float *points = points_tensor.data(); 30 | const int *idx = idx_tensor.data(); 31 | float *out = out_tensor.data(); 32 | 33 | group_points_kernel_launcher_fast(b, c, n, npoints, nsample, points, idx, out); 34 | return 1; 35 | } 36 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/group_points_gpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _GROUP_POINTS_GPU_H 2 | #define _GROUP_POINTS_GPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | int group_points_wrapper_fast(int b, int c, int n, int npoints, int nsample, 11 | at::Tensor points_tensor, at::Tensor idx_tensor, at::Tensor out_tensor); 12 | 13 | void group_points_kernel_launcher_fast(int b, int c, int n, int npoints, int nsample, 14 | const float *points, const int *idx, float *out); 15 | 16 | int group_points_grad_wrapper_fast(int b, int c, int n, int npoints, int nsample, 17 | at::Tensor grad_out_tensor, at::Tensor idx_tensor, at::Tensor grad_points_tensor); 18 | 19 | void group_points_grad_kernel_launcher_fast(int b, int c, int n, int npoints, int nsample, 20 | const float *grad_out, const int *idx, float *grad_points); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/interpolate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | batch version of point interpolation, modified from the original implementation of official PointNet++ codes. 3 | Written by Shaoshuai Shi 4 | All Rights Reserved 2018. 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "interpolate_gpu.h" 16 | 17 | 18 | 19 | 20 | void three_nn_wrapper_fast(int b, int n, int m, at::Tensor unknown_tensor, 21 | at::Tensor known_tensor, at::Tensor dist2_tensor, at::Tensor idx_tensor) { 22 | const float *unknown = unknown_tensor.data(); 23 | const float *known = known_tensor.data(); 24 | float *dist2 = dist2_tensor.data(); 25 | int *idx = idx_tensor.data(); 26 | 27 | three_nn_kernel_launcher_fast(b, n, m, unknown, known, dist2, idx); 28 | } 29 | 30 | 31 | void three_interpolate_wrapper_fast(int b, int c, int m, int n, 32 | at::Tensor points_tensor, 33 | at::Tensor idx_tensor, 34 | at::Tensor weight_tensor, 35 | at::Tensor out_tensor) { 36 | 37 | const float *points = points_tensor.data(); 38 | const float *weight = weight_tensor.data(); 39 | float *out = out_tensor.data(); 40 | const int *idx = idx_tensor.data(); 41 | 42 | three_interpolate_kernel_launcher_fast(b, c, m, n, points, idx, weight, out); 43 | } 44 | 45 | void three_interpolate_grad_wrapper_fast(int b, int c, int n, int m, 46 | at::Tensor grad_out_tensor, 47 | at::Tensor idx_tensor, 48 | at::Tensor weight_tensor, 49 | at::Tensor grad_points_tensor) { 50 | 51 | const float *grad_out = grad_out_tensor.data(); 52 | const float *weight = weight_tensor.data(); 53 | float *grad_points = grad_points_tensor.data(); 54 | const int *idx = idx_tensor.data(); 55 | 56 | three_interpolate_grad_kernel_launcher_fast(b, c, n, m, grad_out, idx, weight, grad_points); 57 | } 58 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/interpolate_gpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTERPOLATE_GPU_H 2 | #define _INTERPOLATE_GPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void three_nn_wrapper_fast(int b, int n, int m, at::Tensor unknown_tensor, 11 | at::Tensor known_tensor, at::Tensor dist2_tensor, at::Tensor idx_tensor); 12 | 13 | void three_nn_kernel_launcher_fast(int b, int n, int m, const float *unknown, 14 | const float *known, float *dist2, int *idx); 15 | 16 | 17 | void three_interpolate_wrapper_fast(int b, int c, int m, int n, at::Tensor points_tensor, 18 | at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor out_tensor); 19 | 20 | void three_interpolate_kernel_launcher_fast(int b, int c, int m, int n, 21 | const float *points, const int *idx, const float *weight, float *out); 22 | 23 | 24 | void three_interpolate_grad_wrapper_fast(int b, int c, int n, int m, at::Tensor grad_out_tensor, 25 | at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor grad_points_tensor); 26 | 27 | void three_interpolate_grad_kernel_launcher_fast(int b, int c, int n, int m, const float *grad_out, 28 | const int *idx, const float *weight, float *grad_points); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/pointnet2_api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ball_query_gpu.h" 5 | #include "group_points_gpu.h" 6 | #include "sampling_gpu.h" 7 | #include "interpolate_gpu.h" 8 | 9 | 10 | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { 11 | m.def("ball_query_wrapper", &ball_query_wrapper_fast, "ball_query_wrapper_fast"); 12 | 13 | m.def("group_points_wrapper", &group_points_wrapper_fast, "group_points_wrapper_fast"); 14 | m.def("group_points_grad_wrapper", &group_points_grad_wrapper_fast, "group_points_grad_wrapper_fast"); 15 | 16 | m.def("gather_points_wrapper", &gather_points_wrapper_fast, "gather_points_wrapper_fast"); 17 | m.def("gather_points_grad_wrapper", &gather_points_grad_wrapper_fast, "gather_points_grad_wrapper_fast"); 18 | 19 | m.def("furthest_point_sampling_wrapper", &furthest_point_sampling_wrapper, "furthest_point_sampling_wrapper"); 20 | 21 | m.def("three_nn_wrapper", &three_nn_wrapper_fast, "three_nn_wrapper_fast"); 22 | m.def("three_interpolate_wrapper", &three_interpolate_wrapper_fast, "three_interpolate_wrapper_fast"); 23 | m.def("three_interpolate_grad_wrapper", &three_interpolate_grad_wrapper_fast, "three_interpolate_grad_wrapper_fast"); 24 | } 25 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/sampling.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | batch version of point sampling and gathering, modified from the original implementation of official PointNet++ codes. 3 | Written by Shaoshuai Shi 4 | All Rights Reserved 2018. 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include "sampling_gpu.h" 12 | 13 | 14 | 15 | 16 | int gather_points_wrapper_fast(int b, int c, int n, int npoints, 17 | at::Tensor points_tensor, at::Tensor idx_tensor, at::Tensor out_tensor){ 18 | const float *points = points_tensor.data(); 19 | const int *idx = idx_tensor.data(); 20 | float *out = out_tensor.data(); 21 | 22 | gather_points_kernel_launcher_fast(b, c, n, npoints, points, idx, out); 23 | return 1; 24 | } 25 | 26 | 27 | int gather_points_grad_wrapper_fast(int b, int c, int n, int npoints, 28 | at::Tensor grad_out_tensor, at::Tensor idx_tensor, at::Tensor grad_points_tensor) { 29 | 30 | const float *grad_out = grad_out_tensor.data(); 31 | const int *idx = idx_tensor.data(); 32 | float *grad_points = grad_points_tensor.data(); 33 | 34 | gather_points_grad_kernel_launcher_fast(b, c, n, npoints, grad_out, idx, grad_points); 35 | return 1; 36 | } 37 | 38 | 39 | int furthest_point_sampling_wrapper(int b, int n, int m, 40 | at::Tensor points_tensor, at::Tensor temp_tensor, at::Tensor idx_tensor) { 41 | 42 | const float *points = points_tensor.data(); 43 | float *temp = temp_tensor.data(); 44 | int *idx = idx_tensor.data(); 45 | 46 | furthest_point_sampling_kernel_launcher(b, n, m, points, temp, idx); 47 | return 1; 48 | } 49 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointnet2_batch/src/sampling_gpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _SAMPLING_GPU_H 2 | #define _SAMPLING_GPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | int gather_points_wrapper_fast(int b, int c, int n, int npoints, 10 | at::Tensor points_tensor, at::Tensor idx_tensor, at::Tensor out_tensor); 11 | 12 | void gather_points_kernel_launcher_fast(int b, int c, int n, int npoints, 13 | const float *points, const int *idx, float *out); 14 | 15 | 16 | int gather_points_grad_wrapper_fast(int b, int c, int n, int npoints, 17 | at::Tensor grad_out_tensor, at::Tensor idx_tensor, at::Tensor grad_points_tensor); 18 | 19 | void gather_points_grad_kernel_launcher_fast(int b, int c, int n, int npoints, 20 | const float *grad_out, const int *idx, float *grad_points); 21 | 22 | 23 | int furthest_point_sampling_wrapper(int b, int n, int m, 24 | at::Tensor points_tensor, at::Tensor temp_tensor, at::Tensor idx_tensor); 25 | 26 | void furthest_point_sampling_kernel_launcher(int b, int n, int m, 27 | const float *dataset, float *temp, int *idxs); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/openpoints/cpp/pointops/__init__.py -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/functions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/openpoints/cpp/pointops/functions/__init__.py -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/setup.py: -------------------------------------------------------------------------------- 1 | #python3 setup.py install 2 | from setuptools import setup 3 | from torch.utils.cpp_extension import BuildExtension, CUDAExtension 4 | import os 5 | from distutils.sysconfig import get_config_vars 6 | 7 | (opt,) = get_config_vars('OPT') 8 | os.environ['OPT'] = " ".join( 9 | flag for flag in opt.split() if flag != '-Wstrict-prototypes' 10 | ) 11 | 12 | setup( 13 | name='pointops', 14 | author='Hengshuang Zhao', 15 | ext_modules=[ 16 | CUDAExtension('pointops_cuda', [ 17 | 'src/pointops_api.cpp', 18 | 'src/knnquery/knnquery_cuda.cpp', 19 | 'src/knnquery/knnquery_cuda_kernel.cu', 20 | 'src/ballquery/ballquery_cuda.cpp', 21 | 'src/ballquery/ballquery_cuda_kernel.cu', 22 | 'src/sampling/sampling_cuda.cpp', 23 | 'src/sampling/sampling_cuda_kernel.cu', 24 | 'src/grouping/grouping_cuda.cpp', 25 | 'src/grouping/grouping_cuda_kernel.cu', 26 | 'src/interpolation/interpolation_cuda.cpp', 27 | 'src/interpolation/interpolation_cuda_kernel.cu', 28 | 'src/subtraction/subtraction_cuda.cpp', 29 | 'src/subtraction/subtraction_cuda_kernel.cu', 30 | 'src/aggregation/aggregation_cuda.cpp', 31 | 'src/aggregation/aggregation_cuda_kernel.cu', 32 | ], 33 | extra_compile_args={'cxx': ['-g'], 'nvcc': ['-O2']} 34 | ) 35 | ], 36 | cmdclass={'build_ext': BuildExtension} 37 | ) 38 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/models/pointnext/PointNeXt/openpoints/cpp/pointops/src/__init__.py -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/aggregation/aggregation_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "aggregation_cuda_kernel.h" 5 | 6 | 7 | void aggregation_forward_cuda(int n, int nsample, int c, int w_c, at::Tensor input_tensor, at::Tensor position_tensor, at::Tensor weight_tensor, at::Tensor idx_tensor, at::Tensor output_tensor) 8 | { 9 | const float *input = input_tensor.data_ptr(); 10 | const float *position = position_tensor.data_ptr(); 11 | const float *weight = weight_tensor.data_ptr(); 12 | const int *idx = idx_tensor.data_ptr(); 13 | float *output = output_tensor.data_ptr(); 14 | aggregation_forward_cuda_launcher(n, nsample, c, w_c, input, position, weight, idx, output); 15 | } 16 | 17 | void aggregation_backward_cuda(int n, int nsample, int c, int w_c, at::Tensor input_tensor, at::Tensor position_tensor, at::Tensor weight_tensor, at::Tensor idx_tensor, at::Tensor grad_output_tensor, at::Tensor grad_input_tensor, at::Tensor grad_position_tensor, at::Tensor grad_weight_tensor) 18 | { 19 | const float *input = input_tensor.data_ptr(); 20 | const float *position = position_tensor.data_ptr(); 21 | const float *weight = weight_tensor.data_ptr(); 22 | const int *idx = idx_tensor.data_ptr(); 23 | const float *grad_output = grad_output_tensor.data_ptr(); 24 | float *grad_input = grad_input_tensor.data_ptr(); 25 | float *grad_position = grad_position_tensor.data_ptr(); 26 | float *grad_weight = grad_weight_tensor.data_ptr(); 27 | aggregation_backward_cuda_launcher(n, nsample, c, w_c, input, position, weight, idx, grad_output, grad_input, grad_position, grad_weight); 28 | } 29 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/aggregation/aggregation_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _AGGREGATION_CUDA_KERNEL 2 | #define _AGGREGATION_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void aggregation_forward_cuda(int n, int nsample, int c, int w_c, at::Tensor input_tensor, at::Tensor position_tensor, at::Tensor weight_tensor, at::Tensor idx_tensor, at::Tensor output_tensor); 8 | void aggregation_backward_cuda(int n, int nsample, int c, int w_c, at::Tensor input_tensor, at::Tensor position_tensor, at::Tensor weight_tensor, at::Tensor idx_tensor, at::Tensor grad_output_tensor, at::Tensor grad_input_tensor, at::Tensor grad_position_tensor, at::Tensor grad_weight_tensor); 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void aggregation_forward_cuda_launcher(int n, int nsample, int c, int w_c, const float *input, const float *position, const float *weight, const int *idx, float *output); 15 | void aggregation_backward_cuda_launcher(int n, int nsample, int c, int w_c, const float *input, const float *position, const float *weight, const int *idx, const float *grad_output, float *grad_input, float *grad_position, float *grad_weight); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/ballquery/ballquery_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _BALL_QUERY_GPU_H 2 | #define _BALL_QUERY_GPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int ballquery_cuda(int m, float radius, int nsample, 9 | at::Tensor xyz_tensor, at::Tensor new_xyz_tensor, 10 | at::Tensor offset_tensor, at::Tensor new_offset_tensor, 11 | at::Tensor idx_tensor); 12 | 13 | void ballquery_launcher(int m, float radius, int nsample, 14 | const float *xyz, const float *new_xyz, 15 | const int *offset, const int *new_offset, int *idx); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/cuda_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _CUDA_UTILS_H 2 | #define _CUDA_UTILS_H 3 | 4 | #include 5 | #include 6 | 7 | #define TOTAL_THREADS 1024 8 | #define THREADS_PER_BLOCK 256 9 | #define DIVUP(m, n) ((m) / (n) + ((m) % (n) > 0)) 10 | 11 | inline int opt_n_threads(int work_size) { 12 | const int pow_2 = std::log(static_cast(work_size)) / std::log(2.0); 13 | return std::max(std::min(1 << pow_2, TOTAL_THREADS), 1); 14 | } 15 | 16 | inline dim3 opt_block_config(int x, int y) { 17 | const int x_threads = opt_n_threads(x); 18 | const int y_threads = std::max(std::min(opt_n_threads(y), TOTAL_THREADS / x_threads), 1); 19 | dim3 block_config(x_threads, y_threads, 1); 20 | return block_config; 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/grouping/grouping_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "grouping_cuda_kernel.h" 5 | 6 | 7 | void grouping_forward_cuda(int m, int nsample, int c, at::Tensor input_tensor, at::Tensor idx_tensor, at::Tensor output_tensor) 8 | { 9 | const float *input = input_tensor.data_ptr(); 10 | const int *idx = idx_tensor.data_ptr(); 11 | float *output = output_tensor.data_ptr(); 12 | grouping_forward_cuda_launcher(m, nsample, c, input, idx, output); 13 | } 14 | 15 | void grouping_backward_cuda(int m, int nsample, int c, at::Tensor grad_output_tensor, at::Tensor idx_tensor, at::Tensor grad_input_tensor) 16 | { 17 | const float *grad_output = grad_output_tensor.data_ptr(); 18 | const int *idx = idx_tensor.data_ptr(); 19 | float *grad_input = grad_input_tensor.data_ptr(); 20 | grouping_backward_cuda_launcher(m, nsample, c, grad_output, idx, grad_input); 21 | } 22 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/grouping/grouping_cuda_kernel.cu: -------------------------------------------------------------------------------- 1 | #include "../cuda_utils.h" 2 | #include "grouping_cuda_kernel.h" 3 | 4 | 5 | __global__ void grouping_forward_cuda_kernel(int m, int nsample, int c, const float *__restrict__ input, const int *__restrict__ idx, float *__restrict__ output) { 6 | // input: input: (n, c), idx: (m, nsample), output: (m, nsample, c) 7 | int index = blockIdx.x * blockDim.x + threadIdx.x; 8 | if (index >= m * nsample * c) return; 9 | const int c_idx = index % c; 10 | const int nsample_idx = (index / c) % nsample; 11 | const int m_idx = index / nsample / c; 12 | const int input_idx = idx[m_idx * nsample + nsample_idx] * c + c_idx; 13 | output[index] = input[input_idx]; 14 | } 15 | 16 | __global__ void grouping_backward_cuda_kernel(int m, int nsample, int c, const float *__restrict__ grad_output, const int *__restrict__ idx, float *__restrict__ grad_input) { 17 | // input: grad_output: (m, nsample, c), idx: (m, nsample), output: grad_input: (n, c) 18 | int index = blockIdx.x * blockDim.x + threadIdx.x; 19 | if (index >= m * nsample * c) return; 20 | const int c_idx = index % c; 21 | const int nsample_idx = (index / c) % nsample; 22 | const int m_idx = index / nsample / c; 23 | const int input_idx = idx[m_idx * nsample + nsample_idx] * c + c_idx; 24 | atomicAdd(grad_input + input_idx, grad_output[index]); 25 | } 26 | 27 | void grouping_forward_cuda_launcher(int m, int nsample, int c, const float *input, const int *idx, float *output) { 28 | // input: input: (n, c), idx: (m, nsample), output: (m, nsample, c) 29 | dim3 blocks(DIVUP(m * nsample * c, THREADS_PER_BLOCK)); 30 | dim3 threads(THREADS_PER_BLOCK); 31 | grouping_forward_cuda_kernel<<>>(m, nsample, c, input, idx, output); 32 | } 33 | 34 | void grouping_backward_cuda_launcher(int m, int nsample, int c, const float *grad_output, const int *idx, float *grad_input) 35 | { 36 | // input: grad_output: (m, nsample, c), idx: (m, nsample), output: grad_input: (n, c) 37 | dim3 blocks(DIVUP(m * nsample * c, THREADS_PER_BLOCK)); 38 | dim3 threads(THREADS_PER_BLOCK); 39 | grouping_backward_cuda_kernel<<>>(m, nsample, c, grad_output, idx, grad_input); 40 | } 41 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/grouping/grouping_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _GROUPING_CUDA_KERNEL 2 | #define _GROUPING_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void grouping_forward_cuda(int m, int nsample, int c, at::Tensor input_tensor, at::Tensor idx_tensor, at::Tensor output_tensor); 8 | void grouping_backward_cuda(int m, int nsample, int c, at::Tensor grad_output_tensor, at::Tensor idx_tensor, at::Tensor grad_input_tensor); 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void grouping_forward_cuda_launcher(int m, int nsample, int c, const float *input, const int *idx, float *output); 15 | void grouping_backward_cuda_launcher(int m, int nsample, int c, const float *grad_output, const int *idx, float *grad_input); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/interpolation/interpolation_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "interpolation_cuda_kernel.h" 5 | 6 | 7 | void interpolation_forward_cuda(int n, int c, int k, at::Tensor input_tensor, at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor output_tensor) 8 | { 9 | const float *input = input_tensor.data_ptr(); 10 | const int *idx = idx_tensor.data_ptr(); 11 | const float *weight = weight_tensor.data_ptr(); 12 | float *output = output_tensor.data_ptr(); 13 | interpolation_forward_cuda_launcher(n, c, k, input, idx, weight, output); 14 | } 15 | 16 | void interpolation_backward_cuda(int n, int c, int k, at::Tensor grad_output_tensor, at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor grad_input_tensor) 17 | { 18 | const float *grad_output = grad_output_tensor.data_ptr(); 19 | const int *idx = idx_tensor.data_ptr(); 20 | const float *weight = weight_tensor.data_ptr(); 21 | float *grad_input = grad_input_tensor.data_ptr(); 22 | interpolation_backward_cuda_launcher(n, c, k, grad_output, idx, weight, grad_input); 23 | } 24 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/interpolation/interpolation_cuda_kernel.cu: -------------------------------------------------------------------------------- 1 | #include "../cuda_utils.h" 2 | #include "interpolation_cuda_kernel.h" 3 | 4 | 5 | __global__ void interpolation_forward_cuda_kernel(int n, int c, int k, const float *input, const int *idx, const float *weight, float *output) 6 | { 7 | // input: input: (m, c), idx: (n, k), weight: (n, k), output: output (n, c) 8 | int index = blockIdx.x * blockDim.x + threadIdx.x; 9 | if (index >= n * c) return; 10 | int c_idx = index % c; 11 | int n_idx = index / c; 12 | for (int i = 0; i < k; i++) 13 | { 14 | int idx_idx = n_idx * k + i; 15 | int input_idx = idx[idx_idx] * c + c_idx; 16 | output[index] += input[input_idx] * weight[idx_idx]; 17 | } 18 | } 19 | 20 | __global__ void interpolation_backward_cuda_kernel(int n, int c, int k, const float *grad_output, const int *idx, const float *weight, float *grad_input) 21 | { 22 | // input: grad_output: (n, c), idx: (n, k), weight: (n, k), output: grad_input (m, c) 23 | int index = blockIdx.x * blockDim.x + threadIdx.x; 24 | if (index >= n * c) return; 25 | int c_idx = index % c; 26 | int n_idx = index / c; 27 | for (int i = 0; i < k; i++) 28 | { 29 | int idx_idx = n_idx * k + i; 30 | int input_idx = idx[idx_idx] * c + c_idx; 31 | atomicAdd(grad_input + input_idx, grad_output[index] * weight[idx_idx]); 32 | } 33 | } 34 | 35 | void interpolation_forward_cuda_launcher(int n, int c, int k, const float *input, const int *idx, const float *weight, float *output) { 36 | // input: input: (m, c), idx: (n, k), weight: (n, k), output: output (n, c) 37 | dim3 blocks(DIVUP(n * c, THREADS_PER_BLOCK)); 38 | dim3 threads(THREADS_PER_BLOCK); 39 | interpolation_forward_cuda_kernel<<>>(n, c, k, input, idx, weight, output); 40 | } 41 | 42 | void interpolation_backward_cuda_launcher(int n, int c, int k, const float *grad_output, const int *idx, const float *weight, float *grad_input) { 43 | // input: grad_output: (n, c), idx: (n, k), weight: (n, k), output: grad_input (m, c) 44 | dim3 blocks(DIVUP(n * c, THREADS_PER_BLOCK)); 45 | dim3 threads(THREADS_PER_BLOCK); 46 | interpolation_backward_cuda_kernel<<>>(n, c, k, grad_output, idx, weight, grad_input); 47 | } 48 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/interpolation/interpolation_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTERPOLATION_CUDA_KERNEL 2 | #define _INTERPOLATION_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void interpolation_forward_cuda(int n, int c, int k, at::Tensor input_tensor, at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor output_tensor); 8 | void interpolation_backward_cuda(int n, int c, int k, at::Tensor grad_output_tensor, at::Tensor idx_tensor, at::Tensor weight_tensor, at::Tensor grad_input_tensor); 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void interpolation_forward_cuda_launcher(int n, int c, int k, const float *input, const int *idx, const float *weight, float *output); 15 | void interpolation_backward_cuda_launcher(int n, int c, int k, const float *grad_output, const int *idx, const float *weight, float *grad_input); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/knnquery/knnquery_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "knnquery_cuda_kernel.h" 5 | 6 | 7 | void knnquery_cuda(int m, int nsample, at::Tensor xyz_tensor, at::Tensor new_xyz_tensor, at::Tensor offset_tensor, at::Tensor new_offset_tensor, at::Tensor idx_tensor, at::Tensor dist2_tensor) 8 | { 9 | const float *xyz = xyz_tensor.data_ptr(); 10 | const float *new_xyz = new_xyz_tensor.data_ptr(); 11 | const int *offset = offset_tensor.data_ptr(); 12 | const int *new_offset = new_offset_tensor.data_ptr(); 13 | int *idx = idx_tensor.data_ptr(); 14 | float *dist2 = dist2_tensor.data_ptr(); 15 | knnquery_cuda_launcher(m, nsample, xyz, new_xyz, offset, new_offset, idx, dist2); 16 | } 17 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/knnquery/knnquery_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _KNNQUERY_CUDA_KERNEL 2 | #define _KNNQUERY_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void knnquery_cuda(int m, int nsample, at::Tensor xyz_tensor, at::Tensor new_xyz_tensor, at::Tensor offset_tensor, at::Tensor new_offset_tensor, at::Tensor idx_tensor, at::Tensor dist2_tensor); 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | void knnquery_cuda_launcher(int m, int nsample, const float *xyz, const float *new_xyz, const int *offset, const int *new_offset, int *idx, float *dist2); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/pointops_api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ballquery/ballquery_cuda_kernel.h" 5 | #include "knnquery/knnquery_cuda_kernel.h" 6 | #include "sampling/sampling_cuda_kernel.h" 7 | #include "grouping/grouping_cuda_kernel.h" 8 | #include "interpolation/interpolation_cuda_kernel.h" 9 | #include "aggregation/aggregation_cuda_kernel.h" 10 | #include "subtraction/subtraction_cuda_kernel.h" 11 | 12 | 13 | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { 14 | m.def("knnquery_cuda", &knnquery_cuda, "knnquery_cuda"); 15 | m.def("ballquery_cuda", &ballquery_cuda, "ballquery_cuda"); 16 | m.def("furthestsampling_cuda", &furthestsampling_cuda, "furthestsampling_cuda"); 17 | m.def("grouping_forward_cuda", &grouping_forward_cuda, "grouping_forward_cuda"); 18 | m.def("grouping_backward_cuda", &grouping_backward_cuda, "grouping_backward_cuda"); 19 | m.def("interpolation_forward_cuda", &interpolation_forward_cuda, "interpolation_forward_cuda"); 20 | m.def("interpolation_backward_cuda", &interpolation_backward_cuda, "interpolation_backward_cuda"); 21 | m.def("subtraction_forward_cuda", &subtraction_forward_cuda, "subtraction_forward_cuda"); 22 | m.def("subtraction_backward_cuda", &subtraction_backward_cuda, "subtraction_backward_cuda"); 23 | m.def("aggregation_forward_cuda", &aggregation_forward_cuda, "aggregation_forward_cuda"); 24 | m.def("aggregation_backward_cuda", &aggregation_backward_cuda, "aggregation_backward_cuda"); 25 | } 26 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/sampling/sampling_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "sampling_cuda_kernel.h" 5 | 6 | 7 | void furthestsampling_cuda(int b, int n, at::Tensor xyz_tensor, at::Tensor offset_tensor, at::Tensor new_offset_tensor, at::Tensor tmp_tensor, at::Tensor idx_tensor) 8 | { 9 | const float *xyz = xyz_tensor.data_ptr(); 10 | const int *offset = offset_tensor.data_ptr(); 11 | const int *new_offset = new_offset_tensor.data_ptr(); 12 | float *tmp = tmp_tensor.data_ptr(); 13 | int *idx = idx_tensor.data_ptr(); 14 | furthestsampling_cuda_launcher(b, n, xyz, offset, new_offset, tmp, idx); 15 | } 16 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/sampling/sampling_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _SAMPLING_CUDA_KERNEL 2 | #define _SAMPLING_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void furthestsampling_cuda(int b, int n, at::Tensor xyz_tensor, at::Tensor offset_tensor, at::Tensor new_offset_tensor, at::Tensor tmp_tensor, at::Tensor idx_tensor); 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | void furthestsampling_cuda_launcher(int b, int n, const float *xyz, const int *offset, const int *new_offset, float *tmp, int *idx); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/subtraction/subtraction_cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "subtraction_cuda_kernel.h" 5 | 6 | 7 | void subtraction_forward_cuda(int n, int nsample, int c, at::Tensor input1_tensor, at::Tensor input2_tensor, at::Tensor idx_tensor, at::Tensor output_tensor) 8 | { 9 | const float *input1 = input1_tensor.data_ptr(); 10 | const float *input2 = input2_tensor.data_ptr(); 11 | const int *idx = idx_tensor.data_ptr(); 12 | float *output = output_tensor.data_ptr(); 13 | subtraction_forward_cuda_launcher(n, nsample, c, input1, input2, idx, output); 14 | } 15 | 16 | void subtraction_backward_cuda(int n, int nsample, int c, at::Tensor idx_tensor, at::Tensor grad_output_tensor, at::Tensor grad_input1_tensor, at::Tensor grad_input2_tensor) 17 | { 18 | const int *idx = idx_tensor.data_ptr(); 19 | const float *grad_output = grad_output_tensor.data_ptr(); 20 | float *grad_input1 = grad_input1_tensor.data_ptr(); 21 | float *grad_input2 = grad_input2_tensor.data_ptr(); 22 | subtraction_backward_cuda_launcher(n, nsample, c, idx, grad_output, grad_input1, grad_input2); 23 | } 24 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/pointops/src/subtraction/subtraction_cuda_kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _SUBTRACTION_CUDA_KERNEL 2 | #define _SUBTRACTION_CUDA_KERNEL 3 | #include 4 | #include 5 | #include 6 | 7 | void subtraction_forward_cuda(int n, int nsample, int c, at::Tensor input1_tensor, at::Tensor input2_tensor, at::Tensor idx_tensor, at::Tensor output_tensor); 8 | void subtraction_backward_cuda(int n, int nsample, int c, at::Tensor idx_tensor, at::Tensor grad_output_tensor, at::Tensor grad_input1_tensor, at::Tensor grad_input2_tensor); 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void subtraction_forward_cuda_launcher(int n, int nsample, int c, const float *input1, const float *input2, const int *idx, float *output); 15 | void subtraction_backward_cuda_launcher(int n, int nsample, int c, const int *idx, const float *grad_output, float *grad_input1, float *grad_input2); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/subsampling/cpp_utils/cloud/cloud.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 0==========================0 4 | // | Local feature test | 5 | // 0==========================0 6 | // 7 | // version 1.0 : 8 | // > 9 | // 10 | //--------------------------------------------------- 11 | // 12 | // Cloud source : 13 | // Define usefull Functions/Methods 14 | // 15 | //---------------------------------------------------- 16 | // 17 | // Hugues THOMAS - 10/02/2017 18 | // 19 | 20 | 21 | #include "cloud.h" 22 | 23 | 24 | // Getters 25 | // ******* 26 | 27 | PointXYZ max_point(std::vector points) 28 | { 29 | // Initiate limits 30 | PointXYZ maxP(points[0]); 31 | 32 | // Loop over all points 33 | for (auto p : points) 34 | { 35 | if (p.x > maxP.x) 36 | maxP.x = p.x; 37 | 38 | if (p.y > maxP.y) 39 | maxP.y = p.y; 40 | 41 | if (p.z > maxP.z) 42 | maxP.z = p.z; 43 | } 44 | 45 | return maxP; 46 | } 47 | 48 | PointXYZ min_point(std::vector points) 49 | { 50 | // Initiate limits 51 | PointXYZ minP(points[0]); 52 | 53 | // Loop over all points 54 | for (auto p : points) 55 | { 56 | if (p.x < minP.x) 57 | minP.x = p.x; 58 | 59 | if (p.y < minP.y) 60 | minP.y = p.y; 61 | 62 | if (p.z < minP.z) 63 | minP.z = p.z; 64 | } 65 | 66 | return minP; 67 | } -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/subsampling/grid_subsampling/grid_subsampling.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "../cpp_utils/cloud/cloud.h" 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class SampledData 11 | { 12 | public: 13 | 14 | // Elements 15 | // ******** 16 | 17 | int count; 18 | PointXYZ point; 19 | vector features; 20 | vector> labels; 21 | 22 | 23 | // Methods 24 | // ******* 25 | 26 | // Constructor 27 | SampledData() 28 | { 29 | count = 0; 30 | point = PointXYZ(); 31 | } 32 | 33 | SampledData(const size_t fdim, const size_t ldim) 34 | { 35 | count = 0; 36 | point = PointXYZ(); 37 | features = vector(fdim); 38 | labels = vector>(ldim); 39 | } 40 | 41 | // Method Update 42 | void update_all(const PointXYZ p, vector::iterator f_begin, vector::iterator l_begin) 43 | { 44 | count += 1; 45 | point += p; 46 | transform (features.begin(), features.end(), f_begin, features.begin(), plus()); 47 | int i = 0; 48 | for(vector::iterator it = l_begin; it != l_begin + labels.size(); ++it) 49 | { 50 | labels[i][*it] += 1; 51 | i++; 52 | } 53 | return; 54 | } 55 | void update_features(const PointXYZ p, vector::iterator f_begin) 56 | { 57 | count += 1; 58 | point += p; 59 | transform (features.begin(), features.end(), f_begin, features.begin(), plus()); 60 | return; 61 | } 62 | void update_classes(const PointXYZ p, vector::iterator l_begin) 63 | { 64 | count += 1; 65 | point += p; 66 | int i = 0; 67 | for(vector::iterator it = l_begin; it != l_begin + labels.size(); ++it) 68 | { 69 | labels[i][*it] += 1; 70 | i++; 71 | } 72 | return; 73 | } 74 | void update_points(const PointXYZ p) 75 | { 76 | count += 1; 77 | point += p; 78 | return; 79 | } 80 | }; 81 | 82 | 83 | 84 | void grid_subsampling(vector& original_points, 85 | vector& subsampled_points, 86 | vector& original_features, 87 | vector& subsampled_features, 88 | vector& original_classes, 89 | vector& subsampled_classes, 90 | float sampleDl, 91 | int verbose); 92 | 93 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/cpp/subsampling/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import numpy.distutils.misc_util 3 | 4 | # Adding OpenCV to project 5 | # ************************ 6 | 7 | # Adding sources of the project 8 | # ***************************** 9 | 10 | m_name = "grid_subsampling" 11 | 12 | SOURCES = ["cpp_utils/cloud/cloud.cpp", 13 | "grid_subsampling/grid_subsampling.cpp", 14 | "wrapper.cpp"] 15 | 16 | module = Extension(m_name, 17 | sources=SOURCES, 18 | extra_compile_args=['-std=c++11', 19 | '-D_GLIBCXX_USE_CXX11_ABI=0']) 20 | 21 | setup(ext_modules=[module], include_dirs=numpy.distutils.misc_util.get_numpy_include_dirs()) 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/__init__.py: -------------------------------------------------------------------------------- 1 | from .data_util import get_features_by_keys, crop_pc, get_class_weights 2 | from .build import build_dataloader_from_cfg, build_dataset_from_cfg 3 | from .vis3d import vis_multi_points, vis_points 4 | from .modelnet import * 5 | from .s3dis import S3DIS, S3DISSphere 6 | from .shapenet import * 7 | from .semantic_kitti import * 8 | from .scanobjectnn import * 9 | from .shapenetpart import * 10 | from .scannetv2 import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/atom3d/__init__.py: -------------------------------------------------------------------------------- 1 | from .psr import Atom2Points, AtomPSR 2 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/atom3d/psr.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | from atom3d.datasets import LMDBDataset 4 | from ..build import DATASETS 5 | from ...transforms import DataTransforms 6 | 7 | prot_atoms = ['C', 'H', 'O', 'N', 'S', 'P', 'ZN', 'NA', 'FE', 'CA', 'MN', 'NI', 'CO', 'MG', 'CU', 'CL', 'SE', 'F'] 8 | 9 | 10 | def one_of_k_encoding_unk(x, allowable_set): 11 | """Converts input to 1-hot encoding given a set of allowable values. Additionally maps inputs not in the allowable set to the last element.""" 12 | if x not in allowable_set: 13 | x = allowable_set[-1] 14 | return list(map(lambda s: x == s, allowable_set)) 15 | 16 | 17 | @DataTransforms.register_module() 18 | class Atom2Points(object): 19 | def __call__(self, item): 20 | # Transform protein into voxel grids. 21 | # Apply random rotation matrix. 22 | id = eval(item['id']) 23 | transformed = { 24 | 'pos': item['atoms'][['x', 'y', 'z']].to_numpy().astype(np.float32), 25 | 'features': np.array([one_of_k_encoding_unk(e, prot_atoms) for e in item['atoms']['element']]).astype(np.float32).transpose(1, 0), 26 | 'label': np.float32(item['scores']['gdt_ts']), 27 | 'target': id[0], 28 | 'decoy': id[1], 29 | } 30 | return transformed 31 | 32 | 33 | @DATASETS.register_module() 34 | class AtomPSR(LMDBDataset): 35 | def __init__(self, data_dir, split, transform=Atom2Points()): 36 | assert split in ['train', 'val', 'test'] 37 | super().__init__(os.path.join(data_dir, split), transform) 38 | 39 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/graph_dataset/__init__.py: -------------------------------------------------------------------------------- 1 | from .graph_dataset import GraphDataset, graphdata_collate 2 | from .svd_encodings_dataset import SVDEncodingsGraphDataset 3 | from .structural_dataset import StructuralDataset 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/grid_sample.py: -------------------------------------------------------------------------------- 1 | import openpoints.cpp.subsampling.grid_subsampling as cpp_subsampling 2 | 3 | 4 | def grid_subsampling(points, features=None, labels=None, sampleDl=0.1, verbose=0): 5 | """ 6 | CPP wrapper for a grid subsampling (method = barycenter for points and features 7 | :param points: (N, 3) matrix of input points 8 | :param features: optional (N, d) matrix of features (floating number) 9 | :param labels: optional (N,) matrix of integer labels 10 | :param sampleDl: parameter defining the size of grid voxels 11 | :param verbose: 1 to display 12 | :return: subsampled points, with features and/or labels depending of the input 13 | """ 14 | if (features is None) and (labels is None): 15 | return cpp_subsampling.compute(points, sampleDl=sampleDl, verbose=verbose) 16 | elif (labels is None): 17 | return cpp_subsampling.compute(points, features=features, sampleDl=sampleDl, verbose=verbose) 18 | elif (features is None): 19 | return cpp_subsampling.compute(points, classes=labels, sampleDl=sampleDl, verbose=verbose) 20 | else: 21 | return cpp_subsampling.compute(points, features=features, classes=labels, sampleDl=sampleDl, verbose=verbose) -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/matterport3d/__init__.py: -------------------------------------------------------------------------------- 1 | from .matterport3d import MP40 2 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/modelnet/__init__.py: -------------------------------------------------------------------------------- 1 | from .modelnet40_normal_resampled_loader import ModelNet 2 | from .modelnet40_ply_2048_loader import ModelNet40Ply2048 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/molhiv/__init__.py: -------------------------------------------------------------------------------- 1 | from .data import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/molhiv/data.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | from ..dataset_base import DatasetBase 4 | from ..graph_dataset import GraphDataset 5 | from ..graph_dataset import SVDEncodingsGraphDataset 6 | from ..graph_dataset import StructuralDataset 7 | 8 | class MOLHIVDataset(DatasetBase): 9 | def __init__(self, 10 | dataset_path , 11 | dataset_name = 'MOLHIV' , 12 | **kwargs 13 | ): 14 | super().__init__(dataset_name = dataset_name, 15 | **kwargs) 16 | self.dataset_path = dataset_path 17 | 18 | @property 19 | def dataset(self): 20 | try: 21 | return self._dataset 22 | except AttributeError: 23 | from ogb.graphproppred import GraphPropPredDataset 24 | self._dataset = GraphPropPredDataset(name='ogbg-molhiv', root=self.dataset_path) 25 | return self._dataset 26 | 27 | @property 28 | def record_tokens(self): 29 | try: 30 | return self._record_tokens 31 | except AttributeError: 32 | split = {'training':'train', 33 | 'validation':'valid', 34 | 'test':'test'}[self.split] 35 | self._record_tokens = self.dataset.get_idx_split()[split] 36 | return self._record_tokens 37 | 38 | def read_record(self, token): 39 | graph, target = self.dataset[token] 40 | graph['num_nodes'] = np.array(graph['num_nodes'], dtype=np.int16) 41 | graph['edges'] = graph.pop('edge_index').T.astype(np.int16) 42 | graph['edge_features'] = graph.pop('edge_feat').astype(np.int16) 43 | graph['node_features'] = graph.pop('node_feat').astype(np.int16) 44 | graph['target'] = np.array(target, np.float32) 45 | return graph 46 | 47 | 48 | 49 | class MOLHIVGraphDataset(GraphDataset,MOLHIVDataset): 50 | pass 51 | 52 | class MOLHIVSVDGraphDataset(SVDEncodingsGraphDataset,MOLHIVDataset): 53 | pass 54 | 55 | class MOLHIVStructuralGraphDataset(StructuralDataset,MOLHIVGraphDataset): 56 | pass 57 | 58 | class MOLHIVStructuralSVDGraphDataset(StructuralDataset,MOLHIVSVDGraphDataset): 59 | pass 60 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/molpcba/__init__.py: -------------------------------------------------------------------------------- 1 | from .data import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/molpcba/data.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | from ..dataset_base import DatasetBase 4 | from ..graph_dataset import GraphDataset 5 | from ..graph_dataset import SVDEncodingsGraphDataset 6 | from ..graph_dataset import StructuralDataset 7 | 8 | class MOLPCBADataset(DatasetBase): 9 | def __init__(self, 10 | dataset_path , 11 | dataset_name = 'MOLPCBA' , 12 | **kwargs 13 | ): 14 | super().__init__(dataset_name = dataset_name, 15 | **kwargs) 16 | self.dataset_path = dataset_path 17 | 18 | @property 19 | def dataset(self): 20 | try: 21 | return self._dataset 22 | except AttributeError: 23 | from ogb.graphproppred import GraphPropPredDataset 24 | self._dataset = GraphPropPredDataset(name='ogbg-molpcba', root=self.dataset_path) 25 | return self._dataset 26 | 27 | @property 28 | def record_tokens(self): 29 | try: 30 | return self._record_tokens 31 | except AttributeError: 32 | split = {'training':'train', 33 | 'validation':'valid', 34 | 'test':'test'}[self.split] 35 | self._record_tokens = self.dataset.get_idx_split()[split] 36 | return self._record_tokens 37 | 38 | def read_record(self, token): 39 | graph, target = self.dataset[token] 40 | graph['num_nodes'] = np.array(graph['num_nodes'], dtype=np.int16) 41 | graph['edges'] = graph.pop('edge_index').T.astype(np.int16) 42 | graph['edge_features'] = graph.pop('edge_feat').astype(np.int16) 43 | graph['node_features'] = graph.pop('node_feat').astype(np.int16) 44 | graph['target'] = np.array(target, np.float32) 45 | return graph 46 | 47 | 48 | 49 | class MOLPCBAGraphDataset(GraphDataset,MOLPCBADataset): 50 | pass 51 | 52 | class MOLPCBASVDGraphDataset(SVDEncodingsGraphDataset,MOLPCBADataset): 53 | pass 54 | 55 | class MOLPCBAStructuralGraphDataset(StructuralDataset,MOLPCBAGraphDataset): 56 | pass 57 | 58 | class MOLPCBAStructuralSVDGraphDataset(StructuralDataset,MOLPCBASVDGraphDataset): 59 | pass 60 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/parsers/__init__.py: -------------------------------------------------------------------------------- 1 | from .parser_factory import create_parser 2 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/parsers/class_map.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def load_class_map(map_or_filename, root=''): 5 | if isinstance(map_or_filename, dict): 6 | assert dict, 'class_map dict must be non-empty' 7 | return map_or_filename 8 | class_map_path = map_or_filename 9 | if not os.path.exists(class_map_path): 10 | class_map_path = os.path.join(root, class_map_path) 11 | assert os.path.exists(class_map_path), 'Cannot locate specified class map file (%s)' % map_or_filename 12 | class_map_ext = os.path.splitext(map_or_filename)[-1].lower() 13 | if class_map_ext == '.txt': 14 | with open(class_map_path) as f: 15 | class_to_idx = {v.strip(): k for k, v in enumerate(f)} 16 | else: 17 | assert False, f'Unsupported class map file extension ({class_map_ext}).' 18 | return class_to_idx 19 | 20 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/parsers/constants.py: -------------------------------------------------------------------------------- 1 | IMG_EXTENSIONS = ('.png', '.jpg', '.jpeg') 2 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/parsers/parser.py: -------------------------------------------------------------------------------- 1 | from abc import abstractmethod 2 | 3 | 4 | class Parser: 5 | def __init__(self): 6 | pass 7 | 8 | @abstractmethod 9 | def _filename(self, index, basename=False, absolute=False): 10 | pass 11 | 12 | def filename(self, index, basename=False, absolute=False): 13 | return self._filename(index, basename=basename, absolute=absolute) 14 | 15 | def filenames(self, basename=False, absolute=False): 16 | return [self._filename(index, basename=basename, absolute=absolute) for index in range(len(self))] 17 | 18 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/parsers/parser_factory.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from .parser_image_folder import ParserImageFolder 4 | from .parser_image_tar import ParserImageTar 5 | from .parser_image_in_tar import ParserImageInTar 6 | 7 | 8 | def create_parser(name, root, split='train', **kwargs): 9 | name = name.lower() 10 | name = name.split('/', 2) 11 | prefix = '' 12 | if len(name) > 1: 13 | prefix = name[0] 14 | name = name[-1] 15 | 16 | # FIXME improve the selection right now just tfds prefix or fallback path, will need options to 17 | # explicitly select other options shortly 18 | if prefix == 'tfds': 19 | from .parser_tfds import ParserTfds # defer tensorflow import 20 | parser = ParserTfds(root, name, split=split, **kwargs) 21 | else: 22 | assert os.path.exists(root) 23 | # default fallback path (backwards compat), use image tar if root is a .tar file, otherwise image folder 24 | # FIXME support split here, in parser? 25 | if os.path.isfile(root) and os.path.splitext(root)[1] == '.tar': 26 | parser = ParserImageInTar(root, **kwargs) 27 | else: 28 | parser = ParserImageFolder(root, **kwargs) 29 | return parser 30 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/pcqm4m/__init__.py: -------------------------------------------------------------------------------- 1 | from .data import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/pcqm4m/data.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | from ..dataset_base import DatasetBase 4 | from ..graph_dataset import GraphDataset 5 | from ..graph_dataset import SVDEncodingsGraphDataset 6 | from ..graph_dataset import StructuralDataset 7 | 8 | class PCQM4MDataset(DatasetBase): 9 | def __init__(self, 10 | dataset_path , 11 | dataset_name = 'PCQM4M', 12 | **kwargs 13 | ): 14 | super().__init__(dataset_name = dataset_name, 15 | **kwargs) 16 | self.dataset_path = dataset_path 17 | 18 | @property 19 | def dataset(self): 20 | try: 21 | return self._dataset 22 | except AttributeError: 23 | from ogb.lsc import PCQM4MDataset 24 | from ogb.utils import smiles2graph 25 | self._smiles2graph = smiles2graph 26 | self._dataset = PCQM4MDataset(root = self.dataset_path, only_smiles=True) 27 | return self._dataset 28 | 29 | @property 30 | def record_tokens(self): 31 | try: 32 | return self._record_tokens 33 | except AttributeError: 34 | split = {'training':'train', 35 | 'validation':'valid', 36 | 'test':'test'}[self.split] 37 | self._record_tokens = self.dataset.get_idx_split()[split] 38 | return self._record_tokens 39 | 40 | def read_record(self, token): 41 | smiles, target = self.dataset[token] 42 | graph = self._smiles2graph(smiles) 43 | graph['num_nodes'] = np.array(graph['num_nodes'], dtype=np.int16) 44 | graph['edges'] = graph.pop('edge_index').T.astype(np.int16) 45 | graph['edge_features'] = graph.pop('edge_feat').astype(np.int16) 46 | graph['node_features'] = graph.pop('node_feat').astype(np.int16) 47 | graph['target'] = np.array(target, np.float32) 48 | return graph 49 | 50 | 51 | 52 | class PCQM4MGraphDataset(GraphDataset,PCQM4MDataset): 53 | pass 54 | 55 | class PCQM4MSVDGraphDataset(SVDEncodingsGraphDataset,PCQM4MDataset): 56 | pass 57 | 58 | class PCQM4MStructuralGraphDataset(StructuralDataset,PCQM4MGraphDataset): 59 | pass 60 | 61 | class PCQM4MStructuralSVDGraphDataset(StructuralDataset,PCQM4MSVDGraphDataset): 62 | pass 63 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/pcqm4mv2/__init__.py: -------------------------------------------------------------------------------- 1 | from .data import * -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/s3dis/__init__.py: -------------------------------------------------------------------------------- 1 | from .s3dis_sphere import S3DISSphere 2 | from .s3dis import S3DIS -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/scannetv2/__init__.py: -------------------------------------------------------------------------------- 1 | from .scannet import ScanNet -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/scanobjectnn/__init__.py: -------------------------------------------------------------------------------- 1 | from .scanobjectnn import ScanObjectNNHardest 2 | 3 | 4 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/__init__.py: -------------------------------------------------------------------------------- 1 | from .semantickitti import SemanticKITTI -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/compile_op.sh: -------------------------------------------------------------------------------- 1 | cd utils/nearest_neighbors 2 | python setup.py install --home="." 3 | cd ../../ 4 | 5 | cd utils/cpp_wrappers 6 | sh compile_wrappers.sh 7 | cd ../../../ -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/cpp_wrappers/compile_wrappers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Compile cpp subsampling 4 | cd cpp_subsampling 5 | python3 setup.py build_ext --inplace 6 | cd .. 7 | 8 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/cpp_wrappers/cpp_subsampling/grid_subsampling/grid_subsampling.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "../../cpp_utils/cloud/cloud.h" 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class SampledData 11 | { 12 | public: 13 | 14 | // Elements 15 | // ******** 16 | 17 | int count; 18 | PointXYZ point; 19 | vector features; 20 | vector> labels; 21 | 22 | 23 | // Methods 24 | // ******* 25 | 26 | // Constructor 27 | SampledData() 28 | { 29 | count = 0; 30 | point = PointXYZ(); 31 | } 32 | 33 | SampledData(const size_t fdim, const size_t ldim) 34 | { 35 | count = 0; 36 | point = PointXYZ(); 37 | features = vector(fdim); 38 | labels = vector>(ldim); 39 | } 40 | 41 | // Method Update 42 | void update_all(const PointXYZ p, vector::iterator f_begin, vector::iterator l_begin) 43 | { 44 | count += 1; 45 | point += p; 46 | transform (features.begin(), features.end(), f_begin, features.begin(), plus()); 47 | int i = 0; 48 | for(vector::iterator it = l_begin; it != l_begin + labels.size(); ++it) 49 | { 50 | labels[i][*it] += 1; 51 | i++; 52 | } 53 | return; 54 | } 55 | void update_features(const PointXYZ p, vector::iterator f_begin) 56 | { 57 | count += 1; 58 | point += p; 59 | transform (features.begin(), features.end(), f_begin, features.begin(), plus()); 60 | return; 61 | } 62 | void update_classes(const PointXYZ p, vector::iterator l_begin) 63 | { 64 | count += 1; 65 | point += p; 66 | int i = 0; 67 | for(vector::iterator it = l_begin; it != l_begin + labels.size(); ++it) 68 | { 69 | labels[i][*it] += 1; 70 | i++; 71 | } 72 | return; 73 | } 74 | void update_points(const PointXYZ p) 75 | { 76 | count += 1; 77 | point += p; 78 | return; 79 | } 80 | }; 81 | 82 | 83 | 84 | void grid_subsampling(vector& original_points, 85 | vector& subsampled_points, 86 | vector& original_features, 87 | vector& subsampled_features, 88 | vector& original_classes, 89 | vector& subsampled_classes, 90 | float sampleDl, 91 | int verbose); 92 | 93 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/cpp_wrappers/cpp_subsampling/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import numpy.distutils.misc_util 3 | 4 | # Adding OpenCV to project 5 | # ************************ 6 | 7 | # Adding sources of the project 8 | # ***************************** 9 | 10 | m_name = "grid_subsampling" 11 | 12 | SOURCES = ["../cpp_utils/cloud/cloud.cpp", 13 | "grid_subsampling/grid_subsampling.cpp", 14 | "wrapper.cpp"] 15 | 16 | module = Extension(m_name, 17 | sources=SOURCES, 18 | extra_compile_args=['-std=c++11', 19 | '-D_GLIBCXX_USE_CXX11_ABI=0']) 20 | 21 | setup(ext_modules=[module], include_dirs=numpy.distutils.misc_util.get_numpy_include_dirs()) 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/cpp_wrappers/cpp_utils/cloud/cloud.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 0==========================0 4 | // | Local feature test | 5 | // 0==========================0 6 | // 7 | // version 1.0 : 8 | // > 9 | // 10 | //--------------------------------------------------- 11 | // 12 | // Cloud source : 13 | // Define usefull Functions/Methods 14 | // 15 | //---------------------------------------------------- 16 | // 17 | // Hugues THOMAS - 10/02/2017 18 | // 19 | 20 | 21 | #include "cloud.h" 22 | 23 | 24 | // Getters 25 | // ******* 26 | 27 | PointXYZ max_point(std::vector points) 28 | { 29 | // Initiate limits 30 | PointXYZ maxP(points[0]); 31 | 32 | // Loop over all points 33 | for (auto p : points) 34 | { 35 | if (p.x > maxP.x) 36 | maxP.x = p.x; 37 | 38 | if (p.y > maxP.y) 39 | maxP.y = p.y; 40 | 41 | if (p.z > maxP.z) 42 | maxP.z = p.z; 43 | } 44 | 45 | return maxP; 46 | } 47 | 48 | PointXYZ min_point(std::vector points) 49 | { 50 | // Initiate limits 51 | PointXYZ minP(points[0]); 52 | 53 | // Loop over all points 54 | for (auto p : points) 55 | { 56 | if (p.x < minP.x) 57 | minP.x = p.x; 58 | 59 | if (p.y < minP.y) 60 | minP.y = p.y; 61 | 62 | if (p.z < minP.z) 63 | minP.z = p.z; 64 | } 65 | 66 | return minP; 67 | } -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/meta/class_names.txt: -------------------------------------------------------------------------------- 1 | ceiling 2 | floor 3 | wall 4 | beam 5 | column 6 | window 7 | door 8 | table 9 | chair 10 | sofa 11 | bookcase 12 | board 13 | clutter 14 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/nearest_neighbors/knn_.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | void cpp_knn(const float* points, const size_t npts, const size_t dim, 5 | const float* queries, const size_t nqueries, 6 | const size_t K, long* indices); 7 | 8 | void cpp_knn_omp(const float* points, const size_t npts, const size_t dim, 9 | const float* queries, const size_t nqueries, 10 | const size_t K, long* indices); 11 | 12 | 13 | void cpp_knn_batch(const float* batch_data, const size_t batch_size, const size_t npts, const size_t dim, 14 | const float* queries, const size_t nqueries, 15 | const size_t K, long* batch_indices); 16 | 17 | void cpp_knn_batch_omp(const float* batch_data, const size_t batch_size, const size_t npts, const size_t dim, 18 | const float* queries, const size_t nqueries, 19 | const size_t K, long* batch_indices); 20 | 21 | void cpp_knn_batch_distance_pick(const float* batch_data, const size_t batch_size, const size_t npts, const size_t dim, 22 | float* queries, const size_t nqueries, 23 | const size_t K, long* batch_indices); 24 | 25 | void cpp_knn_batch_distance_pick_omp(const float* batch_data, const size_t batch_size, const size_t npts, const size_t dim, 26 | float* batch_queries, const size_t nqueries, 27 | const size_t K, long* batch_indices); -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/nearest_neighbors/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | from Cython.Distutils import build_ext 4 | import numpy 5 | 6 | 7 | 8 | ext_modules = [Extension( 9 | "nearest_neighbors", 10 | sources=["knn.pyx", "knn_.cxx",], # source file(s) 11 | include_dirs=["./", numpy.get_include()], 12 | language="c++", 13 | extra_compile_args = [ "-std=c++11", "-fopenmp",], 14 | extra_link_args=["-std=c++11", '-fopenmp'], 15 | )] 16 | 17 | setup( 18 | name = "KNN NanoFLANN", 19 | ext_modules = ext_modules, 20 | cmdclass = {'build_ext': build_ext}, 21 | ) 22 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/semantic_kitti/utils/nearest_neighbors/test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import lib.python.nearest_neighbors as nearest_neighbors 3 | import time 4 | 5 | batch_size = 16 6 | num_points = 81920 7 | K = 16 8 | pc = np.random.rand(batch_size, num_points, 3).astype(np.float32) 9 | 10 | # nearest neighbours 11 | start = time.time() 12 | neigh_idx = nearest_neighbors.knn_batch(pc, pc, K, omp=True) 13 | print(time.time() - start) 14 | 15 | 16 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/shapenet/__init__.py: -------------------------------------------------------------------------------- 1 | from .shapenet55 import ShapeNet 2 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/shapenetpart/__init__.py: -------------------------------------------------------------------------------- 1 | from .shapenetpart import ShapeNetPart, ShapeNetPartNormal -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/dataset/vis2d.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | import torchvision.transforms.functional as F 6 | plt.rcParams["savefig.bbox"] = 'tight' 7 | 8 | 9 | def show_imgs(imgs): 10 | if not isinstance(imgs, list): 11 | imgs = [imgs] 12 | fig, axs = plt.subplots(ncols=len(imgs), squeeze=False) 13 | for i, img in enumerate(imgs): 14 | img = img.detach() 15 | img = F.to_pil_image(img) 16 | axs[0, i].imshow(np.asarray(img)) 17 | axs[0, i].set(xticklabels=[], yticklabels=[], xticks=[], yticks=[]) 18 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/loss/__init__.py: -------------------------------------------------------------------------------- 1 | from .cross_entropy import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy 2 | from .distill_loss import DistillLoss 3 | from .build import build_criterion_from_cfg -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/loss/cross_entropy.py: -------------------------------------------------------------------------------- 1 | """ Cross Entropy w/ smoothing or soft targets 2 | 3 | Borrowed from Ross Wightman (https://www.github.com/timm) 4 | """ 5 | 6 | import torch 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | from .build import LOSS 10 | 11 | 12 | @LOSS.register_module() 13 | class LabelSmoothingCrossEntropy(nn.Module): 14 | """ NLL loss with label smoothing. 15 | """ 16 | def __init__(self, label_smoothing=0.1): 17 | super(LabelSmoothingCrossEntropy, self).__init__() 18 | self.smoothing = label_smoothing 19 | self.confidence = 1. - self.smoothing 20 | 21 | def forward(self, x: torch.Tensor, target: torch.Tensor) -> torch.Tensor: 22 | logprobs = F.log_softmax(x, dim=1) 23 | nll_loss = -logprobs.gather(dim=1, index=target.unsqueeze(1)) 24 | nll_loss = nll_loss.squeeze(1) 25 | smooth_loss = -logprobs.mean(dim=-1) 26 | loss = self.confidence * nll_loss + self.smoothing * smooth_loss 27 | return loss.mean() 28 | 29 | 30 | @LOSS.register_module() 31 | class SoftTargetCrossEntropy(nn.Module): 32 | 33 | def __init__(self, **kwargs): 34 | super(SoftTargetCrossEntropy, self).__init__() 35 | 36 | def forward(self, x: torch.Tensor, target: torch.Tensor) -> torch.Tensor: 37 | loss = torch.sum(-target * F.log_softmax(x, dim=-1), dim=-1) 38 | return loss.mean() 39 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | # from .backbone import PointNextEncoder 6 | from .backbone import * 7 | from .segmentation import * 8 | from .classification import BaseCls 9 | from .reconstruction import MaskedPointViT 10 | from .build import build_model_from_cfg 11 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/backbone/__init__.py: -------------------------------------------------------------------------------- 1 | from .pointnet import PointNetEncoder 2 | from .pointnetv2 import PointNet2Encoder, PointNet2Decoder, PointNetFPModule 3 | from .pointnext import PointNextEncoder, PointNextDecoder 4 | from .dgcnn import DGCNN 5 | from .deepgcn import DeepGCN 6 | from .pointmlp import PointMLPEncoder, PointMLP 7 | from .pointvit import PointViT, PointViTDecoder 8 | from .pct import Pct 9 | from .curvenet import CurveNet 10 | from .simpleview import MVModel -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/build.py: -------------------------------------------------------------------------------- 1 | from openpoints.utils import registry 2 | MODELS = registry.Registry('models') 3 | 4 | 5 | def build_model_from_cfg(cfg, **kwargs): 6 | """ 7 | Build a model, defined by `NAME`. 8 | Args: 9 | cfg (eDICT): 10 | Returns: 11 | Model: a constructed model specified by NAME. 12 | """ 13 | return MODELS.build(cfg, **kwargs) -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/classification/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | from .cls_base import BaseCls, ClsHead -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/layers/__init__.py: -------------------------------------------------------------------------------- 1 | from .weight_init import trunc_normal_, variance_scaling_, lecun_normal_ 2 | from .helpers import MultipleSequential 3 | from .drop import DropBlock2d, DropPath, drop_block_2d, drop_path 4 | from .norm import create_norm 5 | from .activation import create_act 6 | from .mlp import Mlp, GluMlp, GatedMlp, ConvMlp 7 | from .conv import * 8 | from .knn import knn_point, KNN, DilatedKNN 9 | from .group_embed import SubsampleGroup, PointPatchEmbed, P3Embed 10 | from .group import torch_grouping_operation, grouping_operation, gather_operation, create_grouper, get_aggregation_feautres 11 | from .subsample import random_sample, furthest_point_sample, fps # grid_subsampling 12 | from .upsampling import three_interpolate, three_nn, three_interpolation 13 | from .attention import TransformerEncoder 14 | from .local_aggregation import LocalAggregation, CHANNEL_MAP 15 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/layers/activation.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import copy 3 | 4 | 5 | _ACT_LAYER = dict( 6 | silu=nn.SiLU, 7 | swish=nn.SiLU, 8 | mish=nn.Mish, 9 | relu=nn.ReLU, 10 | relu6=nn.ReLU6, 11 | leaky_relu=nn.LeakyReLU, 12 | leakyrelu=nn.LeakyReLU, 13 | elu=nn.ELU, 14 | prelu=nn.PReLU, 15 | celu=nn.CELU, 16 | selu=nn.SELU, 17 | gelu=nn.GELU, 18 | sigmoid=nn.Sigmoid, 19 | tanh=nn.Tanh, 20 | hard_sigmoid=nn.Hardsigmoid, 21 | hard_swish=nn.Hardswish, 22 | ) 23 | 24 | 25 | def create_act(act_args): 26 | """Build activation layer. 27 | Returns: 28 | nn.Module: Created activation layer. 29 | """ 30 | if act_args is None: 31 | return None 32 | act_args = copy.deepcopy(act_args) 33 | 34 | if isinstance(act_args , str): 35 | act_args = {"act": act_args} 36 | 37 | act = act_args.pop('act', None) 38 | if act is None: 39 | return None 40 | 41 | if isinstance(act, str): 42 | act = act.lower() 43 | assert act in _ACT_LAYER.keys(), f"input {act} is not supported" 44 | act_layer = _ACT_LAYER[act] 45 | 46 | inplace = act_args.pop('inplace', True) 47 | 48 | if act not in ['gelu', 'sigmoid']: # TODO: add others 49 | return act_layer(inplace=inplace, **act_args) 50 | else: 51 | return act_layer(**act_args) 52 | 53 | 54 | if __name__ == "__main__": 55 | act_args = {'act': 'relu', 'inplace': False} 56 | act_layer = create_act(act_args) 57 | print(act_layer) 58 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/layers/helpers.py: -------------------------------------------------------------------------------- 1 | """ Layer/Module Helpers 2 | 3 | Hacked together by / Copyright 2020 Ross Wightman 4 | """ 5 | from itertools import repeat 6 | import collections.abc 7 | from torch import nn 8 | 9 | 10 | # From PyTorch internals 11 | def _ntuple(n): 12 | def parse(x): 13 | if isinstance(x, collections.abc.Iterable): 14 | return x 15 | return tuple(repeat(x, n)) 16 | return parse 17 | 18 | 19 | to_1tuple = _ntuple(1) 20 | to_2tuple = _ntuple(2) 21 | to_3tuple = _ntuple(3) 22 | to_4tuple = _ntuple(4) 23 | to_ntuple = _ntuple 24 | 25 | 26 | def make_divisible(v, divisor=8, min_value=None, round_limit=.9): 27 | min_value = min_value or divisor 28 | new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) 29 | # Make sure that round down does not go down by more than 10%. 30 | if new_v < round_limit * v: 31 | new_v += divisor 32 | return new_v 33 | 34 | 35 | 36 | class MultipleSequential(nn.Sequential): 37 | def forward(self, *inputs): 38 | for module in self._modules.values(): 39 | if type(inputs) == tuple: 40 | inputs = module(*inputs) 41 | else: 42 | inputs = module(inputs) 43 | return inputs -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/layers/padding.py: -------------------------------------------------------------------------------- 1 | """ Padding Helpers 2 | 3 | Hacked together by / Copyright 2020 Ross Wightman 4 | """ 5 | import math 6 | from typing import List, Tuple 7 | 8 | import torch.nn.functional as F 9 | 10 | 11 | # Calculate symmetric padding for a convolution 12 | def get_padding(kernel_size: int, stride: int = 1, dilation: int = 1, **_) -> int: 13 | padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2 14 | return padding 15 | 16 | 17 | # Calculate asymmetric TensorFlow-like 'SAME' padding for a convolution 18 | def get_same_padding(x: int, k: int, s: int, d: int): 19 | return max((math.ceil(x / s) - 1) * s + (k - 1) * d + 1 - x, 0) 20 | 21 | 22 | # Can SAME padding for given args be done statically? 23 | def is_static_pad(kernel_size: int, stride: int = 1, dilation: int = 1, **_): 24 | return stride == 1 and (dilation * (kernel_size - 1)) % 2 == 0 25 | 26 | 27 | # Dynamically pad input x with 'SAME' padding for conv with specified args 28 | def pad_same(x, k: List[int], s: List[int], d: List[int] = (1, 1), value: float = 0): 29 | ih, iw = x.size()[-2:] 30 | pad_h, pad_w = get_same_padding(ih, k[0], s[0], d[0]), get_same_padding(iw, k[1], s[1], d[1]) 31 | if pad_h > 0 or pad_w > 0: 32 | x = F.pad(x, [pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2], value=value) 33 | return x 34 | 35 | 36 | def get_padding_value(padding, kernel_size, **kwargs) -> Tuple[Tuple, bool]: 37 | dynamic = False 38 | if isinstance(padding, str): 39 | # for any string padding, the padding will be calculated for you, one of three ways 40 | padding = padding.lower() 41 | if padding == 'same': 42 | # TF compatible 'SAME' padding, has a performance and GPU memory allocation impact 43 | if is_static_pad(kernel_size, **kwargs): 44 | # static case, no extra overhead 45 | padding = get_padding(kernel_size, **kwargs) 46 | else: 47 | # dynamic 'SAME' padding, has runtime/GPU memory overhead 48 | padding = 0 49 | dynamic = True 50 | elif padding == 'valid': 51 | # 'VALID' padding, same as padding=0 52 | padding = 0 53 | else: 54 | # Default to PyTorch style 'same'-ish symmetric padding 55 | padding = get_padding(kernel_size, **kwargs) 56 | return padding, dynamic 57 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/layers/patch_embed.py: -------------------------------------------------------------------------------- 1 | """ Image to Patch Embedding using Conv2d 2 | 3 | A convolution based approach to patchifying a 2D image w/ embedding projection. 4 | 5 | Based on the impl in https://github.com/google-research/vision_transformer 6 | 7 | Hacked together by / Copyright 2020 Ross Wightman 8 | """ 9 | from torch import nn as nn 10 | from .helpers import to_2tuple 11 | 12 | 13 | class PatchEmbed(nn.Module): 14 | """ 2D Image to Patch Embedding 15 | """ 16 | def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768, norm_layer=None, flatten=True): 17 | super().__init__() 18 | img_size = to_2tuple(img_size) 19 | patch_size = to_2tuple(patch_size) 20 | self.img_size = img_size 21 | self.patch_size = patch_size 22 | self.grid_size = (img_size[0] // patch_size[0], img_size[1] // patch_size[1]) 23 | self.num_patches = self.grid_size[0] * self.grid_size[1] 24 | self.flatten = flatten 25 | 26 | self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) 27 | self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity() 28 | 29 | def forward(self, x): 30 | B, C, H, W = x.shape 31 | _assert(H == self.img_size[0], f"Input image height ({H}) doesn't match model ({self.img_size[0]}).") 32 | _assert(W == self.img_size[1], f"Input image width ({W}) doesn't match model ({self.img_size[1]}).") 33 | x = self.proj(x) 34 | if self.flatten: 35 | x = x.flatten(2).transpose(1, 2) # BCHW -> BNC 36 | x = self.norm(x) 37 | return x 38 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/reconstruction/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | from .base_recontruct import MaskedTransformerDecoder, FoldingNet, NodeShuffle 6 | from .maskedpointvit import MaskedPointViT 7 | from .maskedpoint import MaskedPoint 8 | from .maskedpointgroup import MaskedPointGroup 9 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/reconstruction/nodeshuffle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | import itertools, logging 6 | import numpy as np 7 | import torch 8 | import torch.nn as nn 9 | from openpoints.models.build import MODELS 10 | 11 | 12 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/models/segmentation/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | from .base_seg import BaseSeg, SegHead, BasePartSeg, MultiSegHead 6 | # from .vit_seg import PointVitSeg -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/optim/__init__.py: -------------------------------------------------------------------------------- 1 | from .adabelief import AdaBelief 2 | from .adafactor import Adafactor 3 | from .adahessian import Adahessian 4 | from .adamp import AdamP 5 | from .adamw import AdamW 6 | from .lamb import Lamb 7 | from .lars import Lars 8 | from .lookahead import Lookahead 9 | from .madgrad import MADGRAD 10 | from .nadam import Nadam 11 | from .nvnovograd import NvNovoGrad 12 | from .radam import RAdam 13 | from .rmsprop_tf import RMSpropTF 14 | from .sgdp import SGDP 15 | from .optim_factory import build_optimizer_from_cfg, optimizer_kwargs, LayerDecayValueAssigner 16 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/scheduler/__init__.py: -------------------------------------------------------------------------------- 1 | from .cosine_lr import CosineLRScheduler 2 | from .multistep_lr import MultiStepLRScheduler 3 | from .plateau_lr import PlateauLRScheduler 4 | from .poly_lr import PolyLRScheduler 5 | from .step_lr import StepLRScheduler 6 | from .tanh_lr import TanhLRScheduler 7 | 8 | from .scheduler_factory import build_scheduler_from_cfg 9 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/scheduler/multistep_lr.py: -------------------------------------------------------------------------------- 1 | """ MultiStep LR Scheduler 2 | 3 | Basic multi step LR schedule with warmup, noise. 4 | """ 5 | import torch 6 | import bisect 7 | from openpoints.scheduler.scheduler import Scheduler 8 | from typing import List 9 | 10 | class MultiStepLRScheduler(Scheduler): 11 | """ 12 | """ 13 | 14 | def __init__(self, 15 | optimizer: torch.optim.Optimizer, 16 | decay_t: List[int], 17 | decay_rate: float = 1., 18 | warmup_t=0, 19 | warmup_lr_init=0, 20 | t_in_epochs=True, 21 | noise_range_t=None, 22 | noise_pct=0.67, 23 | noise_std=1.0, 24 | noise_seed=42, 25 | initialize=True, 26 | ) -> None: 27 | super().__init__( 28 | optimizer, param_group_field="lr", 29 | noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, 30 | initialize=initialize) 31 | 32 | self.decay_t = decay_t 33 | self.decay_rate = decay_rate 34 | self.warmup_t = warmup_t 35 | self.warmup_lr_init = warmup_lr_init 36 | self.t_in_epochs = t_in_epochs 37 | if self.warmup_t: 38 | self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] 39 | super().update_groups(self.warmup_lr_init) 40 | else: 41 | self.warmup_steps = [1 for _ in self.base_values] 42 | 43 | def get_curr_decay_steps(self, t): 44 | # find where in the array t goes, 45 | # assumes self.decay_t is sorted 46 | return bisect.bisect_right(self.decay_t, t+1) 47 | 48 | def _get_lr(self, t): 49 | if t < self.warmup_t: 50 | lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] 51 | else: 52 | lrs = [v * (self.decay_rate ** self.get_curr_decay_steps(t)) for v in self.base_values] 53 | return lrs 54 | 55 | def get_epoch_values(self, epoch: int): 56 | if self.t_in_epochs: 57 | return self._get_lr(epoch) 58 | else: 59 | return None 60 | 61 | def get_update_values(self, num_updates: int): 62 | if not self.t_in_epochs: 63 | return self._get_lr(num_updates) 64 | else: 65 | return None 66 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/scheduler/step_lr.py: -------------------------------------------------------------------------------- 1 | """ Step Scheduler 2 | 3 | Basic step LR schedule with warmup, noise. 4 | 5 | Hacked together by / Copyright 2020 Ross Wightman 6 | """ 7 | import math 8 | import torch 9 | 10 | from .scheduler import Scheduler 11 | 12 | 13 | class StepLRScheduler(Scheduler): 14 | """ 15 | """ 16 | 17 | def __init__(self, 18 | optimizer: torch.optim.Optimizer, 19 | decay_t: float, 20 | decay_rate: float = 1., 21 | warmup_t=0, 22 | warmup_lr_init=0, 23 | t_in_epochs=True, 24 | noise_range_t=None, 25 | noise_pct=0.67, 26 | noise_std=1.0, 27 | noise_seed=42, 28 | initialize=True, 29 | min_lr=0 30 | ) -> None: 31 | super().__init__( 32 | optimizer, param_group_field="lr", 33 | noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, 34 | initialize=initialize) 35 | 36 | self.decay_t = decay_t 37 | self.decay_rate = decay_rate 38 | self.warmup_t = warmup_t 39 | self.warmup_lr_init = warmup_lr_init 40 | self.t_in_epochs = t_in_epochs 41 | if self.warmup_t: 42 | self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] 43 | super().update_groups(self.warmup_lr_init) 44 | else: 45 | self.warmup_steps = [1 for _ in self.base_values] 46 | self.min_lr = min_lr 47 | 48 | def _get_lr(self, t): 49 | if t < self.warmup_t: 50 | lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] 51 | else: 52 | lrs = [max(v * (self.decay_rate ** (t // self.decay_t)), self.min_lr) for v in self.base_values] 53 | return lrs 54 | 55 | def get_epoch_values(self, epoch: int): 56 | if self.t_in_epochs: 57 | return self._get_lr(epoch) 58 | else: 59 | return None 60 | 61 | def get_update_values(self, num_updates: int): 62 | if not self.t_in_epochs: 63 | return self._get_lr(num_updates) 64 | else: 65 | return None 66 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/transforms/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: PointNeXt 3 | 4 | """ 5 | from .transforms_factory import * 6 | from .point_transformer_gpu import * 7 | from .point_transform_cpu import * 8 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/transforms/transforms_factory.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from ..utils.registry import Registry 3 | 4 | DataTransforms = Registry('datatransforms') 5 | 6 | 7 | def concat_collate_fn(datas): 8 | """collate fn for point transformer 9 | """ 10 | pts, feats, labels, offset, count = [], [], [], [], 0 11 | for data in datas: 12 | count += len(data['pos']) 13 | offset.append(count) 14 | pts.append(data['pos']) 15 | feats.append(data['x']) 16 | labels.append(data['y']) 17 | data = {'pos': torch.cat(pts), 'x': torch.cat(feats), 'y': torch.cat(labels), 18 | 'o': torch.IntTensor(offset)} 19 | return data 20 | 21 | 22 | class Compose(object): 23 | """Composes several transforms together.""" 24 | 25 | def __init__(self, transforms): 26 | self.transforms = transforms 27 | 28 | def __call__(self, args): 29 | for t in self.transforms: 30 | args = t(args) 31 | return args 32 | 33 | 34 | class ListCompose(object): 35 | def __init__(self, transforms): 36 | self.transforms = transforms 37 | 38 | def __call__(self, coord, feat, label): 39 | for t in self.transforms: 40 | coord, feat, label = t(coord, feat, label) 41 | return coord, feat, label 42 | 43 | 44 | def build_transforms_from_cfg(split, datatransforms_cfg): 45 | """ 46 | Build a dataset transform for a certrain split, defined by `datatransforms_cfg`. 47 | """ 48 | transform_list = datatransforms_cfg.get(split, None) 49 | transform_args = datatransforms_cfg.get('kwargs', None) 50 | compose_fn = eval(datatransforms_cfg.get('compose_fn', 'Compose')) 51 | if transform_list is None or len(transform_list) == 0: 52 | return None 53 | point_transforms = [] 54 | if len(transform_list) > 1: 55 | for t in transform_list: 56 | point_transforms.append(DataTransforms.build( 57 | {'NAME': t}, default_args=transform_args)) 58 | return compose_fn(point_transforms) 59 | else: 60 | return DataTransforms.build({'NAME': transform_list[0]}, default_args=transform_args) 61 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .random import set_random_seed 2 | from .config import EasyConfig, print_args 3 | from .logger import setup_logger_dist, generate_exp_directory, resume_exp_directory 4 | from .wandb import Wandb 5 | from .metrics import AverageMeter, ConfusionMatrix, get_mious 6 | from .ckpt_util import resume_model, resume_optimizer, resume_checkpoint, save_checkpoint, load_checkpoint, \ 7 | get_missing_parameters_message, get_unexpected_parameters_message, cal_model_parm_nums 8 | from .dist_utils import reduce_tensor, gather_tensor, find_free_port 9 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/utils/dist_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import torch 3 | from torch import distributed as dist 4 | 5 | 6 | def _init_dist_pytorch(backend, **kwargs): 7 | rank = int(os.environ['RANK']) 8 | num_gpus = torch.cuda.device_count() 9 | torch.cuda.set_device(rank % num_gpus) 10 | dist.init_process_group(backend=backend, **kwargs) 11 | print(f'init distributed in rank {torch.distributed.get_rank()}') 12 | 13 | 14 | def get_dist_info(cfg): 15 | mp = False 16 | if dist.is_available() and dist.is_initialized(): 17 | rank = dist.get_rank() 18 | world_size = dist.get_world_size() 19 | cfg.launcher = 'pytorch' 20 | else: 21 | # only supports 1 node for now 22 | rank = cfg.local_rank 23 | world_size = torch.cuda.device_count() 24 | mp = cfg.launcher in ['mp', 'multiprocessing'] and world_size > 1 25 | distributed = world_size > 1 26 | print(f'launch {cfg.launcher} with {world_size} GPUs, current rank: {rank}') 27 | return rank, world_size, distributed, mp 28 | 29 | 30 | def reduce_tensor(tensor): 31 | ''' 32 | for acc kind, get the mean in each gpu 33 | ''' 34 | rt = tensor.clone() 35 | dist.all_reduce(rt, op=dist.ReduceOp.SUM) 36 | rt /= dist.get_world_size() 37 | return rt 38 | 39 | 40 | def gather_tensor(tensor): 41 | output_tensors = [tensor.clone() for _ in range(dist.get_world_size())] 42 | dist.all_gather(output_tensors, tensor) 43 | concat = torch.cat(output_tensors, dim=0) 44 | return concat 45 | 46 | def find_free_port(): 47 | import socket 48 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 49 | # Binding to port 0 will cause the OS to find an available port for us 50 | sock.bind(("", 0)) 51 | port = sock.getsockname()[1] 52 | sock.close() 53 | # NOTE: there is still a chance the port could be taken by other processes. 54 | return port -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/utils/random.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | import torch 4 | 5 | 6 | def set_random_seed(seed=0, deterministic=False): 7 | random.seed(seed) 8 | np.random.seed(seed) 9 | torch.manual_seed(seed) 10 | torch.cuda.manual_seed(seed) 11 | torch.cuda.manual_seed_all(seed) 12 | torch.backends.cudnn.benchmark = True 13 | 14 | if deterministic: 15 | torch.backends.cudnn.deterministic = True 16 | torch.backends.cudnn.benchmark = False -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/openpoints/utils/str2bool.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | def str2bool(v): 4 | if isinstance(v, bool): 5 | return v 6 | if v.lower() in ('yes', 'true', 't', 'y', '1'): 7 | return True 8 | elif v.lower() in ('no', 'false', 'f', 'n', '0'): 9 | return False 10 | else: 11 | raise argparse.ArgumentTypeError('Boolean value expected.') -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/requirements.txt: -------------------------------------------------------------------------------- 1 | scikit-learn==1.0.2 2 | pickleshare==0.7.5 3 | ninja==1.10.2.3 4 | gdown 5 | easydict==1.9 6 | PyYAML==6.0 7 | protobuf==3.19.4 8 | tensorboard==2.8.0 9 | termcolor==1.1.0 10 | tqdm==4.62.3 11 | multimethod==1.7 12 | h5py==3.6.0 13 | matplotlib==3.5.1 14 | wandb 15 | pyvista 16 | setuptools==59.5.0 17 | Cython==0.29.28 18 | pandas 19 | deepspeed 20 | 21 | # for docs 22 | mkdocs-material 23 | mkdocs-awesome-pages-plugin 24 | mdx_truly_sane_lists 25 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/download_s3dis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | mkdir -p data/S3DIS/ 3 | cd data/S3DIS 4 | gdown https://drive.google.com/uc?id=1MX3ZCnwqyRztG1vFRiHkKTz68ZJeHS4Y 5 | tar -xvf s3disfull.tar 6 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/main_classification.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #SBATCH -N 1 3 | #SBATCH --array=0 4 | #SBATCH -J cls 5 | #SBATCH -o slurm_logs/%x.%3a.%A.out 6 | #SBATCH -e slurm_logs/%x.%3a.%A.err 7 | #SBATCH --time=6:00:00 8 | #SBATCH --nodes=1 9 | #SBATCH --gpus=1 10 | #SBATCH --cpus-per-gpu=6 11 | ##SBATCH --gres=gpu:v100:1 12 | ##SBATCH --mem=30G 13 | 14 | module load cuda/11.1.1 15 | module load gcc 16 | echo "===> Anaconda env loaded" 17 | source activate openpoints 18 | 19 | while true 20 | do 21 | PORT=$(( ((RANDOM<<15)|RANDOM) % 49152 + 10000 )) 22 | status="$(nc -z 127.0.0.1 $PORT < /dev/null &>/dev/null; echo $?)" 23 | if [ "${status}" != "0" ]; then 24 | break; 25 | fi 26 | done 27 | echo $PORT 28 | 29 | nvidia-smi 30 | nvcc --version 31 | 32 | hostname 33 | NUM_GPU_AVAILABLE=`nvidia-smi --query-gpu=name --format=csv,noheader | wc -l` 34 | echo $NUM_GPU_AVAILABLE 35 | 36 | 37 | cfg=$1 38 | PY_ARGS=${@:2} 39 | python examples/classification/main.py --cfg $cfg ${PY_ARGS} 40 | 41 | # how to run 42 | # this script supports training using 1 GPU or multi-gpu, 43 | # simply run jobs on multiple GPUs will launch distributed training by default. 44 | # load different cfgs for training on different benchmarks (modelnet40 classification, or scanobjectnn classification) and using different models. 45 | 46 | # For examples, 47 | # if using a cluster with slurm, train PointNeXt-S on scanobjectnn classification using only 1 GPU, by 3 times: 48 | # sbatch --array=0-2 --gres=gpu:1 --time=10:00:00 main_classification.sh cfgs/scaobjetnn/pointnext-s.yaml 49 | 50 | # if using local machine with GPUs, train PointNeXt-S on scanobjectnn classification using all GPUs 51 | # bash script/main_classification.sh cfgs/scaobjetnn/pointnext-s.yaml 52 | 53 | # if using local machine with GPUs, train PointNeXt-S on scanobjectnn classification using only 1 GPU 54 | # CUDA_VISIBLE_DEVICES=0 bash script/main_classification.sh cfgs/scaobjetnn/pointnext-s.yaml 55 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/main_partseg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #SBATCH -N 1 3 | #SBATCH --array=0 4 | #SBATCH -J partseg 5 | #SBATCH -o slurm_logs/%x.%3a.%A.out 6 | #SBATCH -e slurm_logs/%x.%3a.%A.err 7 | #SBATCH --time=24:00:00 8 | #SBATCH --nodes=1 9 | #SBATCH --gpus=1 10 | #SBATCH --cpus-per-gpu=6 11 | ##SBATCH --gres=gpu:1 12 | ##SBATCH --constraint=[v100] 13 | ##SBATCH --mem=30G 14 | ##SBATCH --mail-type=FAIL,TIME_LIMIT,TIME_LIMIT_90 15 | 16 | 17 | [ ! -d "slurm_logs" ] && echo "Create a directory slurm_logs" && mkdir -p slurm_logs 18 | 19 | module load cuda/11.1.1 20 | module load gcc 21 | 22 | echo "===> Anaconda env loaded" 23 | source activate openpoints 24 | 25 | while true 26 | do 27 | PORT=$(( ((RANDOM<<15)|RANDOM) % 49152 + 10000 )) 28 | status="$(nc -z 127.0.0.1 $PORT < /dev/null &>/dev/null; echo $?)" 29 | if [ "${status}" != "0" ]; then 30 | break; 31 | fi 32 | done 33 | echo $PORT 34 | 35 | nvidia-smi 36 | nvcc --version 37 | 38 | hostname 39 | NUM_GPU_AVAILABLE=`nvidia-smi --query-gpu=name --format=csv,noheader | wc -l` 40 | echo $NUM_GPU_AVAILABLE 41 | 42 | 43 | cfg=$1 44 | PY_ARGS=${@:2} 45 | python examples/shapenetpart/main.py --cfg $cfg ${PY_ARGS} 46 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/main_segmentation.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #SBATCH -N 1 3 | #SBATCH --array=0 4 | #SBATCH -J seg 5 | #SBATCH -o slurm_logs/%x.%3a.%A.out 6 | #SBATCH -e slurm_logs/%x.%3a.%A.err 7 | #SBATCH --time=10:00:00 8 | #SBATCH --gpus=1 9 | #SBATCH --nodes=1 10 | #SBATCH --cpus-per-gpu=6 11 | ##SBATCH --gres=gpu:v100:1 12 | ##SBATCH --mem=30G 13 | 14 | [ ! -d "slurm_logs" ] && echo "Create a directory slurm_logs" && mkdir -p slurm_logs 15 | 16 | module load cuda/11.1.1 17 | module load gcc 18 | 19 | echo "===> Anaconda env loaded" 20 | source ~/.bashrc 21 | source activate openpoints 22 | 23 | nvidia-smi 24 | nvcc --version 25 | 26 | hostname 27 | NUM_GPU_AVAILABLE=`nvidia-smi --query-gpu=name --format=csv,noheader | wc -l` 28 | echo $NUM_GPU_AVAILABLE 29 | 30 | 31 | cfg=$1 32 | PY_ARGS=${@:2} 33 | python examples/segmentation/main.py --cfg $cfg ${PY_ARGS} 34 | 35 | 36 | # how to run 37 | # using slurm, run with 1 GPU, by 3 times (array=0-2): 38 | # sbatch --array=0-2 --gres=gpu:1 --time=12:00:00 script/main_segmentation.sh cfgs/s3dis/pointnext-s.yaml 39 | 40 | # if using local machine with GPUs, run with ALL GPUs: 41 | # bash script/main_segmentation.sh cfgs/s3dis/pointnext-s.yaml 42 | 43 | # local machine, run with 1 GPU: 44 | # CUDA_VISIBLE_DEVICES=0 bash script/main_segmentation.sh cfgs/s3dis/pointnext-s.yaml 45 | -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/profile_flops.sh: -------------------------------------------------------------------------------- 1 | CUDA_VISIBLE_DEVICES=0 python examples/profile.py --cfgs cfgs/s3disfull/pointnet++.yaml num_points=60478 -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/script/test_all_in_one.sh: -------------------------------------------------------------------------------- 1 | export CUDA_VISIBLE_DEVICES=0 2 | 3 | # Scaobjectnn 4 | # pointnet++ 5 | # Loading ckpt @E241, val_macc 0.7793, val_oa 0.8033 6 | # acc per cls is: [0.57831323 0.8743719 0.37593985 0.8172043 0.9230769 0.6666667 7 | # 0.8480392 0.8952381 0.8215768 0.6703704 0.7818182 0.8095238 8 | # 0.78333336 0.9380952 0.90588236] 9 | # ckpt_pth=pretrain/scanobjectnn/scanobjectnn-train-pointnet++-ngpus1-20220331-210646-WswbXmuKRKWtk7mWLhJGTX/checkpoint/scanobjectnn-train-pointnet++-ngpus1-20220331-210646-WswbXmuKRKWtk7mWLhJGTX_ckpt_best.pth 10 | # bash script/main_classification.sh cfgs/scanobjectnn/pointnet++.yaml wandb.use_wandb=False mode=test pretrained_path=$ckpt_pth 11 | 12 | 13 | # pointnet++para 14 | # Loading ckpt @E184, val_macc 0.8322, val_oa 0.8584 15 | # acc per cls is: [0.5903614 0.85427135 0.6766917 0.8736559 0.97179484 0.7266667 16 | # 0.88235295 0.94285715 0.8589212 0.7777778 0.8454546 0.82857144 17 | # 0.84166664 0.97619045 0.8352941 ] 18 | # ckpt_pth=pretrain/scanobjectnn/scanobjectnn-train-pointnet++para-ngpus1-20220331-225749-A2A7QdqG3dKQ2WzjgsqsSZ/checkpoint/scanobjectnn-train-pointnet++para-ngpus1-20220331-225749-A2A7QdqG3dKQ2WzjgsqsSZ_ckpt_best.pth 19 | # CUDA_VISIBLE_DEVICES=0 bash script/main_classification.sh cfgs/scanobjectnn/pointnet++para.yaml wandb.use_wandb=False mode=test pretrained_path=$ckpt_pth 20 | 21 | # pointnext-s 22 | # Loading ckpt @E233, val_macc 0.8648, val_oa 0.8810 23 | # acc per cls is: [0.7108434 0.8844221 0.7368421 0.8844086 0.96410257 0.82666665 24 | # 0.89705884 0.96666664 0.90041494 0.7888889 0.8363636 0.8857143 25 | # 0.825 0.947619 0.91764706] 26 | # ckpt_pth=pretrain/scanobjectnn/scanobjectnn-train-pointnext-s-ngpus1-20220331-210738-LZsAHnzDUmMPAGHJ86pX46/checkpoint/scanobjectnn-train-pointnext-s-ngpus1-20220331-210738-LZsAHnzDUmMPAGHJ86pX46_ckpt_best.pth 27 | # CUDA_VISIBLE_DEVICES=0 bash script/main_classification.sh cfgs/scanobjectnn/pointnext-s.yaml wandb.use_wandb=False mode=test pretrained_path=$ckpt_pth -------------------------------------------------------------------------------- /models/pointnext/PointNeXt/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | git pull --recurse-submodules -------------------------------------------------------------------------------- /models/pointnext/pointnext-s.yaml: -------------------------------------------------------------------------------- 1 | # FLOPs GMACs Params.(M) 2 | # 1.64 0.81 1.367 3 | # 2040.039810480711 4 | 5 | model: 6 | NAME: BaseCls 7 | encoder_args: 8 | NAME: PointNextEncoder 9 | blocks: [1, 1, 1, 1, 1, 1] 10 | strides: [1, 2, 2, 2, 2, 1] 11 | width: 32 12 | in_channels: 4 13 | sa_layers: 2 14 | sa_use_res: True 15 | radius: 0.15 16 | radius_scaling: 1.5 17 | nsample: 32 18 | expansion: 4 19 | aggr_args: 20 | feature_type: 'dp_fj' 21 | reduction: 'max' 22 | group_args: 23 | NAME: 'ballquery' 24 | normalize_dp: True 25 | conv_args: 26 | order: conv-norm-act 27 | act_args: 28 | act: 'relu' 29 | norm_args: 30 | norm: 'bn' 31 | cls_args: 32 | NAME: ClsHead 33 | num_classes: -1 34 | mlps: [512, 256] 35 | norm_args: 36 | norm: 'bn1d' -------------------------------------------------------------------------------- /models/pointnext/pointnext.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | pointnext_dir = './models/pointnext/PointNeXt' 4 | 5 | def add_path_recursive(directory): 6 | sys.path.append(directory) 7 | for root, dirs, files in os.walk(directory): 8 | for d in dirs: 9 | add_path_recursive(os.path.join(root, d)) 10 | 11 | add_path_recursive(pointnext_dir) 12 | 13 | # print(sys.path) 14 | from openpoints.utils import EasyConfig 15 | from openpoints.models import build_model_from_cfg 16 | from openpoints.utils import cal_model_parm_nums 17 | 18 | def PointNEXT(): 19 | cfg_path = './models/pointnext/pointnext-s.yaml' 20 | 21 | cfg = EasyConfig() 22 | cfg.load(cfg_path, recursive=True) 23 | 24 | model = build_model_from_cfg(cfg.model) 25 | model_size = cal_model_parm_nums(model) 26 | print("model size:") 27 | print(model_size) 28 | 29 | return model -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | easydict==1.9 2 | timm==0.4.12 3 | ftfy==6.0.1 4 | regex==2022.10.31 5 | pyyaml_env_tag==0.1 6 | h5py==3.6.0 7 | open3d==0.16.0 8 | wandb==0.13.3 9 | termcolor==1.1.0 10 | lmdb==1.3.0 11 | open-clip-torch==2.24.0 -------------------------------------------------------------------------------- /scripts/pretrain_pointbert.sh: -------------------------------------------------------------------------------- 1 | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m torch.distributed.launch --nproc_per_node=8 main.py --model ULIP_PointBERT --npoints 8192 --lr 3e-3 --output-dir ./outputs/reproduce_pointbert_8kpts_version_dataset 2 | -------------------------------------------------------------------------------- /scripts/pretrain_pointmlp.sh: -------------------------------------------------------------------------------- 1 | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m torch.distributed.launch --nproc_per_node=8 main.py --model ULIP_PN_MLP --npoints 8192 --lr 1e-3 --output-dir ./outputs/reproduce_pointmlp_8kpts -------------------------------------------------------------------------------- /scripts/pretrain_pointnet2_ssg.sh: -------------------------------------------------------------------------------- 1 | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m torch.distributed.launch --nproc_per_node=8 main.py --model ULIP_PN_SSG --npoints 8192 --lr 3e-3 --output-dir ./outputs/reproduce_pointnet2_ssg_8kpts -------------------------------------------------------------------------------- /scripts/pretrain_pointnext.sh: -------------------------------------------------------------------------------- 1 | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m torch.distributed.launch --nproc_per_node=8 main.py --model ULIP_PN_NEXT --npoints 8192 --output-dir ./outputs/reproduce_pointnext_8kpts --lr 1e-3 --use_height -------------------------------------------------------------------------------- /scripts/test_pointbert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointbert_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP_PointBERT --npoints 8192 --output-dir $output_dir --evaluate_3d --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /scripts/test_pointmlp.sh: -------------------------------------------------------------------------------- 1 | test_pointbert.sh#!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointmlp_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP_PN_MLP --npoints 8192 --output-dir $output_dir --evaluate_3d --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /scripts/test_pointnet2_ssg.sh: -------------------------------------------------------------------------------- 1 | test_pointbert.sh#!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointnet2_ssg_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP_PN_SSG --npoints 8192 --output-dir $output_dir --evaluate_3d --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /scripts/test_pointnext.sh: -------------------------------------------------------------------------------- 1 | test_pointbert.sh#!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointnext_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP_PN_NEXT --npoints 8192 --output-dir $output_dir --evaluate_3d --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /scripts/test_ulip2_pointbert_modelnet40.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointbert_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP2_PointBERT_Colored --npoints 10000 --output-dir $output_dir --evaluate_3d_ulip2 --validate_dataset_name=modelnet40 --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /scripts/test_ulip2_pointbert_objaverse_lvis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Please provide a *.pt file as input" 5 | exit 1 6 | fi 7 | 8 | model_file=$1 9 | output_dir=./outputs/test_pointbert_8kpts 10 | 11 | CUDA_VISIBLE_DEVICES=0 python main.py --model ULIP2_PointBERT_Colored --npoints 10000 --output-dir $output_dir --evaluate_3d_ulip2 --validate_dataset_name=objaverse_lvis_colored --test_ckpt_addr $model_file 2>&1 | tee $output_dir/log.txt -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | * Copyright (c) 2023, salesforce.com, inc. 3 | * All rights reserved. 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause 6 | * By Le Xue 7 | ''' 8 | -------------------------------------------------------------------------------- /utils/bpe_simple_vocab_16e6.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salesforce/ULIP/5e7c0da470fc16717030ec4116b0f81d4d2b4823/utils/bpe_simple_vocab_16e6.txt.gz -------------------------------------------------------------------------------- /utils/build.py: -------------------------------------------------------------------------------- 1 | from utils import registry 2 | 3 | 4 | DATASETS = registry.Registry('dataset') 5 | 6 | 7 | def build_dataset_from_cfg(cfg, default_args = None): 8 | """ 9 | Build a dataset, defined by `dataset_name`. 10 | Args: 11 | cfg (eDICT): 12 | Returns: 13 | Dataset: a constructed dataset specified by dataset_name. 14 | """ 15 | return DATASETS.build(cfg, default_args = default_args) 16 | 17 | 18 | -------------------------------------------------------------------------------- /utils/config.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | from easydict import EasyDict 3 | import os 4 | from .logger import print_log 5 | 6 | def log_args_to_file(args, pre='args', logger=None): 7 | for key, val in args.__dict__.items(): 8 | print_log(f'{pre}.{key} : {val}', logger = logger) 9 | 10 | def log_config_to_file(cfg, pre='cfg', logger=None): 11 | for key, val in cfg.items(): 12 | if isinstance(cfg[key], EasyDict): 13 | print_log(f'{pre}.{key} = edict()', logger = logger) 14 | log_config_to_file(cfg[key], pre=pre + '.' + key, logger=logger) 15 | continue 16 | print_log(f'{pre}.{key} : {val}', logger = logger) 17 | 18 | def merge_new_config(config, new_config): 19 | for key, val in new_config.items(): 20 | if not isinstance(val, dict): 21 | if key == '_base_': 22 | with open(new_config['_base_'], 'r') as f: 23 | try: 24 | val = yaml.load(f, Loader=yaml.FullLoader) 25 | except: 26 | val = yaml.load(f) 27 | config[key] = EasyDict() 28 | merge_new_config(config[key], val) 29 | else: 30 | config[key] = val 31 | continue 32 | if key not in config: 33 | config[key] = EasyDict() 34 | merge_new_config(config[key], val) 35 | return config 36 | 37 | def cfg_from_yaml_file(cfg_file): 38 | config = EasyDict() 39 | with open(cfg_file, 'r') as f: 40 | try: 41 | new_config = yaml.load(f, Loader=yaml.FullLoader) 42 | except: 43 | new_config = yaml.load(f) 44 | merge_new_config(config=config, new_config=new_config) 45 | return config 46 | 47 | def get_config(args, logger=None): 48 | if args.resume: 49 | cfg_path = os.path.join(args.experiment_path, 'config.yaml') 50 | if not os.path.exists(cfg_path): 51 | print_log("Failed to resume", logger = logger) 52 | raise FileNotFoundError() 53 | print_log(f'Resume yaml from {cfg_path}', logger = logger) 54 | args.config = cfg_path 55 | config = cfg_from_yaml_file(args.config) 56 | if not args.resume and args.local_rank == 0: 57 | save_experiment_config(args, config, logger) 58 | return config 59 | 60 | def save_experiment_config(args, config, logger = None): 61 | config_path = os.path.join(args.experiment_path, 'config.yaml') 62 | os.system('cp %s %s' % (args.config, config_path)) 63 | print_log(f'Copy the Config file from {args.config} to {config_path}',logger = logger ) -------------------------------------------------------------------------------- /utils/io.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import numpy as np 3 | import open3d 4 | import os 5 | 6 | class IO: 7 | @classmethod 8 | def get(cls, file_path): 9 | _, file_extension = os.path.splitext(file_path) 10 | 11 | if file_extension in ['.npy']: 12 | return cls._read_npy(file_path) 13 | elif file_extension in ['.pcd']: 14 | return cls._read_pcd(file_path) 15 | elif file_extension in ['.h5']: 16 | return cls._read_h5(file_path) 17 | elif file_extension in ['.txt']: 18 | return cls._read_txt(file_path) 19 | else: 20 | raise Exception('Unsupported file extension: %s' % file_extension) 21 | 22 | # References: https://github.com/numpy/numpy/blob/master/numpy/lib/format.py 23 | @classmethod 24 | def _read_npy(cls, file_path): 25 | return np.load(file_path) 26 | 27 | # References: https://github.com/dimatura/pypcd/blob/master/pypcd/pypcd.py#L275 28 | # Support PCD files without compression ONLY! 29 | @classmethod 30 | def _read_pcd(cls, file_path): 31 | pc = open3d.io.read_point_cloud(file_path) 32 | ptcloud = np.array(pc.points) 33 | return ptcloud 34 | 35 | @classmethod 36 | def _read_txt(cls, file_path): 37 | return np.loadtxt(file_path) 38 | 39 | @classmethod 40 | def _read_h5(cls, file_path): 41 | f = h5py.File(file_path, 'r') 42 | return f['data'][()] --------------------------------------------------------------------------------