Skip to content

Commit 5782540

Browse files
Fix affine() IndexError with boolean mask indexing (#1502) (#1547)
Replace img[mask] = fill_img[mask] with torch::where(mask, fill_img, img) in THSVision_ApplyGridTransform's Nearest-mode fill logic. The operator[] boolean mask indexing is not supported in recent LibTorch versions. This fixes torchvision.transforms.functional.affine() and rotate() when called with a fill value and Nearest interpolation mode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 297f8cb commit 5782540

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

src/Native/LibTorchSharp/THSVision.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ Tensor THSVision_ApplyGridTransform(Tensor i, Tensor g, const int8_t m, const fl
184184

185185
if (m == 0) {
186186
mask = mask < 0.5;
187-
img[mask] = fill_img[mask];
187+
img = torch::where(mask, fill_img, img);
188188
}
189189
else {
190190
img = img * mask + (-mask + 1.0) * fill_img;

test/TorchSharpTest/TestTorchVision.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,60 @@ public void TestRotateImage45DegreesClockwise()
11431143
}
11441144
}
11451145

1146+
[Fact]
1147+
public void TestAffineTransform3D()
1148+
{
1149+
// 3D input: [C, H, W]
1150+
var img = torch.rand(new long[] { 1, 48, 48 });
1151+
var result = functional.affine(
1152+
img,
1153+
angle: 0f,
1154+
translate: new[] { 0, 0 },
1155+
scale: 1f,
1156+
shear: new[] { 1f, 1f },
1157+
fill: 0);
1158+
Assert.Equal(img.shape, result.shape);
1159+
}
1160+
1161+
[Fact]
1162+
public void TestAffineTransform4D()
1163+
{
1164+
// 4D input: [N, C, H, W] — reproduces issue #1502
1165+
var img = torch.rand(new long[] { 1, 1, 48, 48 });
1166+
var result = functional.affine(
1167+
img,
1168+
angle: 0f,
1169+
translate: new[] { 0, 0 },
1170+
scale: 1f,
1171+
shear: new[] { 1f, 1f },
1172+
fill: 0);
1173+
Assert.Equal(img.shape, result.shape);
1174+
}
1175+
1176+
[Fact]
1177+
public void TestAffineTransform4DBatch()
1178+
{
1179+
// 4D input with batch > 1
1180+
var img = torch.rand(new long[] { 4, 3, 32, 32 });
1181+
var result = functional.affine(
1182+
img,
1183+
angle: 15f,
1184+
translate: new[] { 5, 5 },
1185+
scale: 0.9f,
1186+
shear: new[] { 10f, 5f },
1187+
fill: 0);
1188+
Assert.Equal(img.shape, result.shape);
1189+
}
1190+
1191+
[Fact]
1192+
public void TestRotateWithFill()
1193+
{
1194+
// Rotate with fill also uses ApplyGridTransform — verify it works
1195+
var img = torch.rand(new long[] { 1, 1, 48, 48 });
1196+
var result = functional.rotate(img, 45f, InterpolationMode.Nearest, fill: new float[] { 0f });
1197+
Assert.Equal(img.shape, result.shape);
1198+
}
1199+
11461200
[Fact]
11471201
public void Solarize_InvertedPixel_True()
11481202
{

0 commit comments

Comments
 (0)