avoid running tests twice

Summary: Avoid test files explicitly importing TestCase objects from each other, because doing so causes the tests to be discovered twice by unittest discover. This means moving a few static functions out of their classes. I noticed this while trying to fix failures from yesterday.

Reviewed By: nikhilaravi

Differential Revision: D28194679

fbshipit-source-id: ac6e6585603bd4ef9c098cdd56891d94f8923ba6
This commit is contained in:
Jeremy Reizenstein 2021-05-07 05:03:10 -07:00 committed by Facebook GitHub Bot
parent e3624b4e9d
commit 0ca839cc32
4 changed files with 165 additions and 171 deletions

View File

@ -6,7 +6,7 @@ import torch
from common_testing import TestCaseMixin from common_testing import TestCaseMixin
from pytorch3d.loss import mesh_edge_loss from pytorch3d.loss import mesh_edge_loss
from pytorch3d.structures import Meshes from pytorch3d.structures import Meshes
from test_sample_points_from_meshes import TestSamplePoints from test_sample_points_from_meshes import init_meshes
class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase): class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
@ -92,7 +92,7 @@ class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
@staticmethod @staticmethod
def mesh_edge_loss(num_meshes: int = 10, max_v: int = 100, max_f: int = 300): def mesh_edge_loss(num_meshes: int = 10, max_v: int = 100, max_f: int = 300):
meshes = TestSamplePoints.init_meshes(num_meshes, max_v, max_f, device="cuda:0") meshes = init_meshes(num_meshes, max_v, max_f, device="cuda:0")
torch.cuda.synchronize() torch.cuda.synchronize()
def compute_loss(): def compute_loss():

View File

@ -10,20 +10,14 @@ from common_testing import TestCaseMixin
from pytorch3d.structures.meshes import Meshes from pytorch3d.structures.meshes import Meshes
class TestMeshes(TestCaseMixin, unittest.TestCase): def init_mesh(
def setUp(self) -> None:
np.random.seed(42)
torch.manual_seed(42)
@staticmethod
def init_mesh(
num_meshes: int = 10, num_meshes: int = 10,
max_v: int = 100, max_v: int = 100,
max_f: int = 300, max_f: int = 300,
lists_to_tensors: bool = False, lists_to_tensors: bool = False,
device: str = "cpu", device: str = "cpu",
requires_grad: bool = False, requires_grad: bool = False,
): ):
""" """
Function to generate a Meshes object of N meshes with Function to generate a Meshes object of N meshes with
random numbers of vertices and faces. random numbers of vertices and faces.
@ -66,9 +60,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
device=device, device=device,
requires_grad=requires_grad, requires_grad=requires_grad,
) )
faces = torch.randint( faces = torch.randint(v[i], size=(f[i], 3), dtype=torch.int64, device=device)
v[i], size=(f[i], 3), dtype=torch.int64, device=device
)
verts_list.append(verts) verts_list.append(verts)
faces_list.append(faces) faces_list.append(faces)
@ -78,8 +70,8 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
return Meshes(verts=verts_list, faces=faces_list) return Meshes(verts=verts_list, faces=faces_list)
@staticmethod
def init_simple_mesh(device: str = "cpu"): def init_simple_mesh(device: str = "cpu"):
""" """
Returns a Meshes data structure of simple mesh examples. Returns a Meshes data structure of simple mesh examples.
@ -130,8 +122,14 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
] ]
return Meshes(verts=verts, faces=faces) return Meshes(verts=verts, faces=faces)
class TestMeshes(TestCaseMixin, unittest.TestCase):
def setUp(self) -> None:
np.random.seed(42)
torch.manual_seed(42)
def test_simple(self): def test_simple(self):
mesh = TestMeshes.init_simple_mesh("cuda:0") mesh = init_simple_mesh("cuda:0")
# Check that faces/verts per mesh are set in init: # Check that faces/verts per mesh are set in init:
self.assertClose(mesh._num_faces_per_mesh.cpu(), torch.tensor([1, 2, 7])) self.assertClose(mesh._num_faces_per_mesh.cpu(), torch.tensor([1, 2, 7]))
@ -168,7 +166,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
# Check if correct errors are raised when verts/faces are on # Check if correct errors are raised when verts/faces are on
# different devices # different devices
mesh = TestMeshes.init_mesh(10, 10, 100) mesh = init_mesh(10, 10, 100)
verts_list = mesh.verts_list() # all tensors on cpu verts_list = mesh.verts_list() # all tensors on cpu
verts_list = [ verts_list = [
v.to("cuda:0") if random.uniform(0, 1) > 0.5 else v for v in verts_list v.to("cuda:0") if random.uniform(0, 1) > 0.5 else v for v in verts_list
@ -192,7 +190,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
# Define the test mesh object either as a list or tensor of faces/verts. # Define the test mesh object either as a list or tensor of faces/verts.
for lists_to_tensors in (False, True): for lists_to_tensors in (False, True):
N = 10 N = 10
mesh = TestMeshes.init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors) mesh = init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors)
verts_list = mesh.verts_list() verts_list = mesh.verts_list()
faces_list = mesh.faces_list() faces_list = mesh.faces_list()
@ -361,7 +359,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
def test_clone(self): def test_clone(self):
N = 5 N = 5
mesh = TestMeshes.init_mesh(N, 10, 100) mesh = init_mesh(N, 10, 100)
for force in [0, 1]: for force in [0, 1]:
if force: if force:
# force mesh to have computed attributes # force mesh to have computed attributes
@ -386,7 +384,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
def test_detach(self): def test_detach(self):
N = 5 N = 5
mesh = TestMeshes.init_mesh(N, 10, 100, requires_grad=True) mesh = init_mesh(N, 10, 100, requires_grad=True)
for force in [0, 1]: for force in [0, 1]:
if force: if force:
# force mesh to have computed attributes # force mesh to have computed attributes
@ -425,7 +423,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
# Note that we don't test with random meshes for this case, as the # Note that we don't test with random meshes for this case, as the
# definition of Laplacian is defined for simple graphs (aka valid meshes) # definition of Laplacian is defined for simple graphs (aka valid meshes)
meshes = TestMeshes.init_simple_mesh("cuda:0") meshes = init_simple_mesh("cuda:0")
lapl_naive = naive_laplacian_packed(meshes) lapl_naive = naive_laplacian_packed(meshes)
lapl = meshes.laplacian_packed().to_dense() lapl = meshes.laplacian_packed().to_dense()
@ -443,7 +441,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
return Meshes(verts=new_verts_list, faces=new_faces_list) return Meshes(verts=new_verts_list, faces=new_faces_list)
N = 5 N = 5
mesh = TestMeshes.init_mesh(N, 30, 100, lists_to_tensors=True) mesh = init_mesh(N, 30, 100, lists_to_tensors=True)
all_v = mesh.verts_packed().size(0) all_v = mesh.verts_packed().size(0)
verts_per_mesh = mesh.num_verts_per_mesh() verts_per_mesh = mesh.num_verts_per_mesh()
for force, deform_shape in itertools.product([False, True], [(all_v, 3), 3]): for force, deform_shape in itertools.product([False, True], [(all_v, 3), 3]):
@ -577,7 +575,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
N = 5 N = 5
for test in ["tensor", "scalar"]: for test in ["tensor", "scalar"]:
for force in (False, True): for force in (False, True):
mesh = TestMeshes.init_mesh(N, 10, 100, lists_to_tensors=True) mesh = init_mesh(N, 10, 100, lists_to_tensors=True)
if force: if force:
# force mesh to have computed attributes # force mesh to have computed attributes
mesh.verts_packed() mesh.verts_packed()
@ -686,7 +684,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
def test_extend_list(self): def test_extend_list(self):
N = 10 N = 10
mesh = TestMeshes.init_mesh(5, 10, 100) mesh = init_mesh(5, 10, 100)
for force in [0, 1]: for force in [0, 1]:
if force: if force:
# force some computes to happen # force some computes to happen
@ -721,7 +719,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
mesh.extend(N=-1) mesh.extend(N=-1)
def test_to(self): def test_to(self):
mesh = TestMeshes.init_mesh(5, 10, 100, device=torch.device("cuda:0")) mesh = init_mesh(5, 10, 100, device=torch.device("cuda:0"))
device = torch.device("cuda:1") device = torch.device("cuda:1")
new_mesh = mesh.to(device) new_mesh = mesh.to(device)
@ -729,7 +727,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
self.assertTrue(mesh.device == torch.device("cuda:0")) self.assertTrue(mesh.device == torch.device("cuda:0"))
def test_split_mesh(self): def test_split_mesh(self):
mesh = TestMeshes.init_mesh(5, 10, 100) mesh = init_mesh(5, 10, 100)
split_sizes = [2, 3] split_sizes = [2, 3]
split_meshes = mesh.split(split_sizes) split_meshes = mesh.split(split_sizes)
self.assertTrue(len(split_meshes[0]) == 2) self.assertTrue(len(split_meshes[0]) == 2)
@ -756,9 +754,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
N = 10 N = 10
for lists_to_tensors in (False, True): for lists_to_tensors in (False, True):
for force in (True, False): for force in (True, False):
mesh = TestMeshes.init_mesh( mesh = init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors)
N, 100, 300, lists_to_tensors=lists_to_tensors
)
num_verts_per_mesh = mesh.num_verts_per_mesh() num_verts_per_mesh = mesh.num_verts_per_mesh()
if force: if force:
# force mesh to have computed attributes # force mesh to have computed attributes
@ -1166,7 +1162,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
num_meshes = 10 num_meshes = 10
max_v = 100 max_v = 100
max_f = 300 max_f = 300
mesh_cpu = TestMeshes.init_mesh(num_meshes, max_v, max_f, device="cpu") mesh_cpu = init_mesh(num_meshes, max_v, max_f, device="cpu")
device = torch.device("cuda:0") device = torch.device("cuda:0")
mesh_cuda = mesh_cpu.to(device) mesh_cuda = mesh_cpu.to(device)
@ -1187,7 +1183,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
def compute_packed_with_init( def compute_packed_with_init(
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu" num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
): ):
mesh = TestMeshes.init_mesh(num_meshes, max_v, max_f, device=device) mesh = init_mesh(num_meshes, max_v, max_f, device=device)
torch.cuda.synchronize() torch.cuda.synchronize()
def compute_packed(): def compute_packed():
@ -1200,7 +1196,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
def compute_padded_with_init( def compute_padded_with_init(
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu" num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
): ):
mesh = TestMeshes.init_mesh(num_meshes, max_v, max_f, device=device) mesh = init_mesh(num_meshes, max_v, max_f, device=device)
torch.cuda.synchronize() torch.cuda.synchronize()
def compute_padded(): def compute_padded():

View File

@ -33,19 +33,13 @@ DEBUG = False
DATA_DIR = get_tests_dir() / "data" DATA_DIR = get_tests_dir() / "data"
class TestSamplePoints(TestCaseMixin, unittest.TestCase): def init_meshes(
def setUp(self) -> None:
super().setUp()
torch.manual_seed(1)
@staticmethod
def init_meshes(
num_meshes: int = 10, num_meshes: int = 10,
num_verts: int = 1000, num_verts: int = 1000,
num_faces: int = 3000, num_faces: int = 3000,
device: str = "cpu", device: str = "cpu",
add_texture: bool = False, add_texture: bool = False,
): ):
device = torch.device(device) device = torch.device(device)
verts_list = [] verts_list = []
faces_list = [] faces_list = []
@ -68,6 +62,12 @@ class TestSamplePoints(TestCaseMixin, unittest.TestCase):
return meshes return meshes
class TestSamplePoints(TestCaseMixin, unittest.TestCase):
def setUp(self) -> None:
super().setUp()
torch.manual_seed(1)
def test_all_empty_meshes(self): def test_all_empty_meshes(self):
""" """
Check sample_points_from_meshes raises an exception if all meshes are Check sample_points_from_meshes raises an exception if all meshes are
@ -298,9 +298,7 @@ class TestSamplePoints(TestCaseMixin, unittest.TestCase):
def test_outputs(self): def test_outputs(self):
for add_texture in (True, False): for add_texture in (True, False):
meshes = TestSamplePoints.init_meshes( meshes = init_meshes(device=torch.device("cuda:0"), add_texture=add_texture)
device=torch.device("cuda:0"), add_texture=add_texture
)
out1 = sample_points_from_meshes(meshes, num_samples=100) out1 = sample_points_from_meshes(meshes, num_samples=100)
self.assertTrue(torch.is_tensor(out1)) self.assertTrue(torch.is_tensor(out1))

View File

@ -15,7 +15,7 @@ from pytorch3d.renderer.mesh.textures import (
pack_rectangles, pack_rectangles,
) )
from pytorch3d.structures import Meshes, list_to_packed, packed_to_list from pytorch3d.structures import Meshes, list_to_packed, packed_to_list
from test_meshes import TestMeshes from test_meshes import init_mesh
def tryindex(self, index, tex, meshes, source): def tryindex(self, index, tex, meshes, source):
@ -173,7 +173,7 @@ class TestTexturesVertex(TestCaseMixin, unittest.TestCase):
def test_extend(self): def test_extend(self):
B = 10 B = 10
mesh = TestMeshes.init_mesh(B, 30, 50) mesh = init_mesh(B, 30, 50)
V = mesh._V V = mesh._V
tex_uv = TexturesVertex(verts_features=torch.randn((B, V, 3))) tex_uv = TexturesVertex(verts_features=torch.randn((B, V, 3)))
tex_mesh = Meshes( tex_mesh = Meshes(
@ -379,7 +379,7 @@ class TestTexturesAtlas(TestCaseMixin, unittest.TestCase):
def test_extend(self): def test_extend(self):
B = 10 B = 10
mesh = TestMeshes.init_mesh(B, 30, 50) mesh = init_mesh(B, 30, 50)
F = mesh._F F = mesh._F
tex_uv = TexturesAtlas(atlas=torch.randn((B, F, 2, 2, 3))) tex_uv = TexturesAtlas(atlas=torch.randn((B, F, 2, 2, 3)))
tex_mesh = Meshes( tex_mesh = Meshes(
@ -667,7 +667,7 @@ class TestTexturesUV(TestCaseMixin, unittest.TestCase):
def test_extend(self): def test_extend(self):
B = 5 B = 5
mesh = TestMeshes.init_mesh(B, 30, 50) mesh = init_mesh(B, 30, 50)
V = mesh._V V = mesh._V
num_faces = mesh.num_faces_per_mesh() num_faces = mesh.num_faces_per_mesh()
num_verts = mesh.num_verts_per_mesh() num_verts = mesh.num_verts_per_mesh()