| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | import os |
| | import argparse |
| | import numpy as np |
| | from time import time |
| | from urllib.request import urlretrieve |
| |
|
| | try: |
| | import open3d as o3d |
| | except ImportError: |
| | raise ImportError("Please install open3d-python with `pip install open3d`.") |
| |
|
| | import torch |
| | import torch.nn as nn |
| | from torch.optim import SGD |
| |
|
| | import MinkowskiEngine as ME |
| | from examples.minkunet import MinkUNet34C |
| |
|
| | import torch.nn.parallel as parallel |
| |
|
| | if not os.path.isfile("weights.pth"): |
| | urlretrieve("http://cvgl.stanford.edu/data2/minkowskiengine/1.ply", "1.ply") |
| |
|
| | parser = argparse.ArgumentParser() |
| | parser.add_argument("--file_name", type=str, default="1.ply") |
| | parser.add_argument("--batch_size", type=int, default=4) |
| | parser.add_argument("--max_ngpu", type=int, default=2) |
| |
|
| | cache = {} |
| |
|
| |
|
| | def load_file(file_name, voxel_size): |
| | if file_name not in cache: |
| | pcd = o3d.io.read_point_cloud(file_name) |
| | cache[file_name] = pcd |
| |
|
| | pcd = cache[file_name] |
| | quantized_coords, feats = ME.utils.sparse_quantize( |
| | np.array(pcd.points, dtype=np.float32), |
| | np.array(pcd.colors, dtype=np.float32), |
| | quantization_size=voxel_size, |
| | ) |
| | random_labels = torch.zeros(len(feats)) |
| |
|
| | return quantized_coords, feats, random_labels |
| |
|
| |
|
| | def generate_input(file_name, voxel_size): |
| | |
| | batch = [load_file(file_name, voxel_size)] |
| | coordinates_, featrues_, labels_ = list(zip(*batch)) |
| | coordinates, features, labels = ME.utils.sparse_collate( |
| | coordinates_, featrues_, labels_ |
| | ) |
| |
|
| | |
| | return coordinates, (features - 0.5).float(), labels |
| |
|
| |
|
| | if __name__ == "__main__": |
| | |
| | config = parser.parse_args() |
| | num_devices = torch.cuda.device_count() |
| | num_devices = min(config.max_ngpu, num_devices) |
| | devices = list(range(num_devices)) |
| | print("''''''''''''''''''''''''''''''''''''''''''''''''''''''''''") |
| | print("' WARNING: This example is deprecated. '") |
| | print("' Please use DistributedDataParallel or pytorch-lightning'") |
| | print("''''''''''''''''''''''''''''''''''''''''''''''''''''''''''") |
| | print( |
| | f"Testing {num_devices} GPUs. Total batch size: {num_devices * config.batch_size}" |
| | ) |
| |
|
| | |
| | target_device = devices[0] |
| |
|
| | |
| | net = MinkUNet34C(3, 20, D=3) |
| | net = net.to(target_device) |
| |
|
| | |
| | net = ME.MinkowskiSyncBatchNorm.convert_sync_batchnorm(net) |
| | optimizer = SGD(net.parameters(), lr=1e-1) |
| |
|
| | |
| | criterion = nn.CrossEntropyLoss() |
| | criterions = parallel.replicate(criterion, devices) |
| | min_time = np.inf |
| |
|
| | for iteration in range(10): |
| | optimizer.zero_grad() |
| |
|
| | |
| | inputs, all_labels = [], [] |
| | for i in range(num_devices): |
| | coordinates, features, labels = generate_input(config.file_name, 0.05) |
| | with torch.cuda.device(devices[i]): |
| | inputs.append(ME.SparseTensor(features, coordinates, device=devices[i])) |
| | all_labels.append(labels.long().to(devices[i])) |
| |
|
| | |
| | st = time() |
| | replicas = parallel.replicate(net, devices) |
| | outputs = parallel.parallel_apply(replicas, inputs, devices=devices) |
| |
|
| | |
| | out_features = [output.F for output in outputs] |
| | losses = parallel.parallel_apply( |
| | criterions, tuple(zip(out_features, all_labels)), devices=devices |
| | ) |
| | loss = parallel.gather(losses, target_device, dim=0).mean() |
| | |
| | loss.backward() |
| | optimizer.step() |
| |
|
| | t = time() - st |
| | min_time = min(t, min_time) |
| | print( |
| | f"Iteration: {iteration}, Loss: {loss.item()}, Time: {t}, Min time: {min_time}" |
| | ) |
| |
|
| | |
| | if iteration % 10 == 0: |
| | torch.cuda.empty_cache() |
| |
|