diff --git a/.gitignore b/.gitignore
index 965f454b120a263cf52c304fdb4a069f3c4cafec..20ef211dc58e9119808e643a382564eb66459318 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,10 @@ desktop.ini
# HF Spaces
.huggingface/
+# Hunyuan3D-2.1 — training data and compiled artifacts not needed at inference
+Hunyuan3D-2.1/hy3dshape/tools/mini_trainset/
+Hunyuan3D-2.1/hy3dshape/tools/mini_testset/
+
# Logs
*.log
logs/
diff --git a/Hunyuan3D-2.1/.gitattributes b/Hunyuan3D-2.1/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..43b06ad45d40d0c9b5824e9cf75a3d52691d5987
--- /dev/null
+++ b/Hunyuan3D-2.1/.gitattributes
@@ -0,0 +1,343 @@
+*.7z filter=lfs diff=lfs merge=lfs -text
+*.arrow filter=lfs diff=lfs merge=lfs -text
+*.bin filter=lfs diff=lfs merge=lfs -text
+*.bz2 filter=lfs diff=lfs merge=lfs -text
+*.ckpt filter=lfs diff=lfs merge=lfs -text
+*.ftz filter=lfs diff=lfs merge=lfs -text
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.h5 filter=lfs diff=lfs merge=lfs -text
+*.joblib filter=lfs diff=lfs merge=lfs -text
+*.lfs.* filter=lfs diff=lfs merge=lfs -text
+*.mlmodel filter=lfs diff=lfs merge=lfs -text
+*.model filter=lfs diff=lfs merge=lfs -text
+*.msgpack filter=lfs diff=lfs merge=lfs -text
+*.npy filter=lfs diff=lfs merge=lfs -text
+*.npz filter=lfs diff=lfs merge=lfs -text
+*.onnx filter=lfs diff=lfs merge=lfs -text
+*.ot filter=lfs diff=lfs merge=lfs -text
+*.parquet filter=lfs diff=lfs merge=lfs -text
+*.pb filter=lfs diff=lfs merge=lfs -text
+*.pickle filter=lfs diff=lfs merge=lfs -text
+*.pkl filter=lfs diff=lfs merge=lfs -text
+*.pt filter=lfs diff=lfs merge=lfs -text
+*.pth filter=lfs diff=lfs merge=lfs -text
+*.rar filter=lfs diff=lfs merge=lfs -text
+*.safetensors filter=lfs diff=lfs merge=lfs -text
+saved_model/**/* filter=lfs diff=lfs merge=lfs -text
+*.tar.* filter=lfs diff=lfs merge=lfs -text
+*.tar filter=lfs diff=lfs merge=lfs -text
+*.tflite filter=lfs diff=lfs merge=lfs -text
+*.tgz filter=lfs diff=lfs merge=lfs -text
+*.wasm filter=lfs diff=lfs merge=lfs -text
+*.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.zst filter=lfs diff=lfs merge=lfs -text
+*tfevents* filter=lfs diff=lfs merge=lfs -text
+assets/1.glb filter=lfs diff=lfs merge=lfs -text
+assets/demo.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/052.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/073.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/075.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1008.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/101.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1022.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1029.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1111.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1123.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1128.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1135.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1146.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1148.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1154.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1180.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1196.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1204.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1234.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1310.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1316.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1354.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1429.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1493.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1582.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1583.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1596.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1601.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1603.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1626.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1627.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/167.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1670.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1679.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1687.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1698.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1715.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1735.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1738.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1744.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1758.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1772.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1773.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1778.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/1898.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/191.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/195.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/197.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/198.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/202.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/203.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/218.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/219.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/379.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/380.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/419.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/888.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/895.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g0k031h3nikcok2105nmanksg8l5pbbr7bqo.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g34o31hmm0kqa42405np612cg9dc6aqccf38.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g34o31hmv1te73a3048jtdvj4c5rbhtrtu98.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g34o31hnup72ck24g5nue8l108b6nb88hkf8.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g34o31hoft434340g5og0ja2oco7h0k4l5ro.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g3k031hitndtdk2605orjhoonrn9pgo7vls0.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g3k831ho6lsmo3ujg5pf2trqjcqh7vvmb00g.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g3k831hp7srtcjoe05nihqp1g8rq0th69ncg.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_1040g3k831hpb3dlt3idg5nr0msu0907jusb30n8.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17459220925801040g00831gddt2hh3a4g4a11mgjsgcu8r915tdg.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17459220948541040g00831gddt2hh3a604a11mgjsgcu87ec4kd0.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17459234709671040g00831g0tg76cge6g5n2g1pd4m8g1ijr22c8.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17461776897281040g2sg31gvoem3pjqeg5pvr5s839cu1ae9vono.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17461776916821040g2sg31gvoem3pjqf05pvr5s839cu1pkdjmf8.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17478460238811040g00831hoen1ga3u0g5oha0d441i3j1s6i7eo.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/Camera_XHS_17480136679411040g00831hn2tbsojucg5pl27pu7c1mcgk10jug.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/ainimal_14.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/ainimal_17.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/ainimal_21.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/ainimal_9.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng1.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng11.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng14.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng16.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng18.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng2.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng20.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng22.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng37.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng42.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng43.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng44.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng54.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng6.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng63.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng64.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng65.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng75.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/jimeng82.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/kaijia_qie.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/mmexport02df348f675e40d6e3828fae4cb8f2b3_1746117674020.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/mmexportde235211f304fd83ec9d60e38c9f6f0b_1747975667632.png filter=lfs diff=lfs merge=lfs -text
+assets/example_images/qie.png filter=lfs diff=lfs merge=lfs -text
+assets/images/pipeline.png filter=lfs diff=lfs merge=lfs -text
+assets/images/teaser.jpg filter=lfs diff=lfs merge=lfs -text
+hy3dpaint/assets/case_1/image.png filter=lfs diff=lfs merge=lfs -text
+hy3dpaint/assets/case_1/mesh.glb filter=lfs diff=lfs merge=lfs -text
+hy3dpaint/assets/case_2/image.png filter=lfs diff=lfs merge=lfs -text
+hy3dpaint/assets/case_2/mesh.glb filter=lfs diff=lfs merge=lfs -text
+hy3dshape/demos/demo.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_testset/images/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_testset/images/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_testset/images/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/00a4cff37043361068376104a292f5b44b5eacbd174651553b6a7ae35647a2a6/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af803d6846d1d2c80e65ba349345f00369141bf130f8169737b85e641bdff0e/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1af9172118894bad49159607b6083d3f2ae35d39e2a436da980684b990ae835c/render_cond/mesh.ply filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/1b81d3db8cb44f423a35c644253fb37392670f744f6881f964a3cd712740d3d4/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e47ce1dc421d6638e36c0a6766fd35f8e54ab1280a59199dbf850622c5c47bc/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/2e558708f817780dceee9d0c4f50748e683afadb78475c4c84f97fce7062d6bc/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/3c443fa7d3db9274512b79526118fae1b9fb13b59df7f90deec587ed62aa936d/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/000.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/001.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/002.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/003.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/004.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/005.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/006.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/007.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/008.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/009.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/010.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/011.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/012.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/013.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/014.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/015.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/016.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/017.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/018.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/019.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/020.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/021.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/022.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/023.png filter=lfs diff=lfs merge=lfs -text
+hy3dshape/tools/mini_trainset/preprocessed/7dc69acf647a7ef597f0c9462097370f2c8f8e212f9fd1e7f3547f45b3f3a3d8/render_cond/mesh.ply filter=lfs diff=lfs merge=lfs -text
+custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
+custom_rasterizer-0.1-cp310-cp310-linux_x86_64_torch_2.7.1_cu126.whl filter=lfs diff=lfs merge=lfs -text
diff --git a/Hunyuan3D-2.1/.gitignore b/Hunyuan3D-2.1/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1666c9838071f36e9f86f98c5057bb2614485909
--- /dev/null
+++ b/Hunyuan3D-2.1/.gitignore
@@ -0,0 +1,183 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+!hy3dpaint/packages/custom_rasterizer/lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# UV
+# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+#uv.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+.DS_Store
+# Cython debug symbols
+cython_debug/
+gradio_cache/
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+
+
+
+hy3dshape/tools/cmd*.sh
+hy3dshape/output_folder/
+demo.glb
+demo_textured.glb
+demo_textured.jpg
+demo_textured.mtl
+demo_textured_metallic.jpg
+demo_textured_roughness.jpg
+demo_untextured.glb
+white_mesh_remesh.obj
diff --git a/Hunyuan3D-2.1/LICENSE b/Hunyuan3D-2.1/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..96313b341082fb9f72a00b7c77accd8196390af0
--- /dev/null
+++ b/Hunyuan3D-2.1/LICENSE
@@ -0,0 +1,81 @@
+TENCENT HUNYUAN 3D 2.1 COMMUNITY LICENSE AGREEMENT
+Tencent Hunyuan 3D 2.1 Release Date: June 13, 2025
+THIS LICENSE AGREEMENT DOES NOT APPLY IN THE EUROPEAN UNION, UNITED KINGDOM AND SOUTH KOREA AND IS EXPRESSLY LIMITED TO THE TERRITORY, AS DEFINED BELOW.
+By clicking to agree or by using, reproducing, modifying, distributing, performing or displaying any portion or element of the Tencent Hunyuan 3D 2.1 Works, including via any Hosted Service, You will be deemed to have recognized and accepted the content of this Agreement, which is effective immediately.
+1. DEFINITIONS.
+a. “Acceptable Use Policy” shall mean the policy made available by Tencent as set forth in the Exhibit A.
+b. “Agreement” shall mean the terms and conditions for use, reproduction, distribution, modification, performance and displaying of Tencent Hunyuan 3D 2.1 Works or any portion or element thereof set forth herein.
+c. “Documentation” shall mean the specifications, manuals and documentation for Tencent Hunyuan 3D 2.1 made publicly available by Tencent.
+d. “Hosted Service” shall mean a hosted service offered via an application programming interface (API), web access, or any other electronic or remote means.
+e. “Licensee,” “You” or “Your” shall mean a natural person or legal entity exercising the rights granted by this Agreement and/or using the Tencent Hunyuan 3D 2.1 Works for any purpose and in any field of use.
+f. “Materials” shall mean, collectively, Tencent’s proprietary Tencent Hunyuan 3D 2.1 and Documentation (and any portion thereof) as made available by Tencent under this Agreement.
+g. “Model Derivatives” shall mean all: (i) modifications to Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; (ii) works based on Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; or (iii) any other machine learning model which is created by transfer of patterns of the weights, parameters, operations, or Output of Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1, to that model in order to cause that model to perform similarly to Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1, including distillation methods, methods that use intermediate data representations, or methods based on the generation of synthetic data Outputs by Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1 for training that model. For clarity, Outputs by themselves are not deemed Model Derivatives.
+h. “Output” shall mean the information and/or content output of Tencent Hunyuan 3D 2.1 or a Model Derivative that results from operating or otherwise using Tencent Hunyuan 3D 2.1 or a Model Derivative, including via a Hosted Service.
+i. “Tencent,” “We” or “Us” shall mean THL Q Limited.
+j. “Tencent Hunyuan 3D 2.1” shall mean the 3D generation models and their software and algorithms, including trained model weights, parameters (including optimizer states), machine-learning model code, inference-enabling code, training-enabling code, fine-tuning enabling code and other elements of the foregoing made publicly available by Us at [ https://github.com/Tencent-Hunyuan/Hunyuan3D-2.1].
+k. “Tencent Hunyuan 3D 2.1 Works” shall mean: (i) the Materials; (ii) Model Derivatives; and (iii) all derivative works thereof.
+l. “Territory” shall mean the worldwide territory, excluding the territory of the European Union, United Kingdom and South Korea.
+m. “Third Party” or “Third Parties” shall mean individuals or legal entities that are not under common control with Us or You.
+n. “including” shall mean including but not limited to.
+2. GRANT OF RIGHTS.
+We grant You, for the Territory only, a non-exclusive, non-transferable and royalty-free limited license under Tencent’s intellectual property or other rights owned by Us embodied in or utilized by the Materials to use, reproduce, distribute, create derivative works of (including Model Derivatives), and make modifications to the Materials, only in accordance with the terms of this Agreement and the Acceptable Use Policy, and You must not violate (or encourage or permit anyone else to violate) any term of this Agreement or the Acceptable Use Policy.
+3. DISTRIBUTION.
+You may, subject to Your compliance with this Agreement, distribute or make available to Third Parties the Tencent Hunyuan 3D 2.1 Works, exclusively in the Territory, provided that You meet all of the following conditions:
+a. You must provide all such Third Party recipients of the Tencent Hunyuan 3D 2.1 Works or products or services using them a copy of this Agreement;
+b. You must cause any modified files to carry prominent notices stating that You changed the files;
+c. You are encouraged to: (i) publish at least one technology introduction blogpost or one public statement expressing Your experience of using the Tencent Hunyuan 3D 2.1 Works; and (ii) mark the products or services developed by using the Tencent Hunyuan 3D 2.1 Works to indicate that the product/service is “Powered by Tencent Hunyuan”; and
+d. All distributions to Third Parties (other than through a Hosted Service) must be accompanied by a “Notice” text file that contains the following notice: “Tencent Hunyuan 3D 2.1 is licensed under the Tencent Hunyuan 3D 2.1 Community License Agreement, Copyright © 2025 Tencent. All Rights Reserved. The trademark rights of “Tencent Hunyuan” are owned by Tencent or its affiliate.”
+You may add Your own copyright statement to Your modifications and, except as set forth in this Section and in Section 5, may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Model Derivatives as a whole, provided Your use, reproduction, modification, distribution, performance and display of the work otherwise complies with the terms and conditions of this Agreement (including as regards the Territory). If You receive Tencent Hunyuan 3D 2.1 Works from a Licensee as part of an integrated end user product, then this Section 3 of this Agreement will not apply to You.
+4. ADDITIONAL COMMERCIAL TERMS.
+If, on the Tencent Hunyuan 3D 2.1 version release date, the monthly active users of all products or services made available by or for Licensee is greater than 1 million monthly active users in the preceding calendar month, You must request a license from Tencent, which Tencent may grant to You in its sole discretion, and You are not authorized to exercise any of the rights under this Agreement unless or until Tencent otherwise expressly grants You such rights.
+Subject to Tencent's written approval, you may request a license for the use of Tencent Hunyuan 3D 2.1 by submitting the following information to hunyuan3d@tencent.com:
+a. Your company’s name and associated business sector that plans to use Tencent Hunyuan 3D 2.1.
+b. Your intended use case and the purpose of using Tencent Hunyuan 3D 2.1.
+c. Your plans to modify Tencent Hunyuan 3D 2.1 or create Model Derivatives.
+5. RULES OF USE.
+a. Your use of the Tencent Hunyuan 3D 2.1 Works must comply with applicable laws and regulations (including trade compliance laws and regulations) and adhere to the Acceptable Use Policy for the Tencent Hunyuan 3D 2.1 Works, which is hereby incorporated by reference into this Agreement. You must include the use restrictions referenced in these Sections 5(a) and 5(b) as an enforceable provision in any agreement (e.g., license agreement, terms of use, etc.) governing the use and/or distribution of Tencent Hunyuan 3D 2.1 Works and You must provide notice to subsequent users to whom You distribute that Tencent Hunyuan 3D 2.1 Works are subject to the use restrictions in these Sections 5(a) and 5(b).
+b. You must not use the Tencent Hunyuan 3D 2.1 Works or any Output or results of the Tencent Hunyuan 3D 2.1 Works to improve any other AI model (other than Tencent Hunyuan 3D 2.1 or Model Derivatives thereof).
+c. You must not use, reproduce, modify, distribute, or display the Tencent Hunyuan 3D 2.1 Works, Output or results of the Tencent Hunyuan 3D 2.1 Works outside the Territory. Any such use outside the Territory is unlicensed and unauthorized under this Agreement.
+6. INTELLECTUAL PROPERTY.
+a. Subject to Tencent’s ownership of Tencent Hunyuan 3D 2.1 Works made by or for Tencent and intellectual property rights therein, conditioned upon Your compliance with the terms and conditions of this Agreement, as between You and Tencent, You will be the owner of any derivative works and modifications of the Materials and any Model Derivatives that are made by or for You.
+b. No trademark licenses are granted under this Agreement, and in connection with the Tencent Hunyuan 3D 2.1 Works, Licensee may not use any name or mark owned by or associated with Tencent or any of its affiliates, except as required for reasonable and customary use in describing and distributing the Tencent Hunyuan 3D 2.1 Works. Tencent hereby grants You a license to use “Tencent Hunyuan” (the “Mark”) in the Territory solely as required to comply with the provisions of Section 3(c), provided that You comply with any applicable laws related to trademark protection. All goodwill arising out of Your use of the Mark will inure to the benefit of Tencent.
+c. If You commence a lawsuit or other proceedings (including a cross-claim or counterclaim in a lawsuit) against Us or any person or entity alleging that the Materials or any Output, or any portion of any of the foregoing, infringe any intellectual property or other right owned or licensable by You, then all licenses granted to You under this Agreement shall terminate as of the date such lawsuit or other proceeding is filed. You will defend, indemnify and hold harmless Us from and against any claim by any Third Party arising out of or related to Your or the Third Party’s use or distribution of the Tencent Hunyuan 3D 2.1 Works.
+d. Tencent claims no rights in Outputs You generate. You and Your users are solely responsible for Outputs and their subsequent uses.
+7. DISCLAIMERS OF WARRANTY AND LIMITATIONS OF LIABILITY.
+a. We are not obligated to support, update, provide training for, or develop any further version of the Tencent Hunyuan 3D 2.1 Works or to grant any license thereto.
+b. UNLESS AND ONLY TO THE EXTENT REQUIRED BY APPLICABLE LAW, THE TENCENT HUNYUAN 3D 2.1 WORKS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND INCLUDING ANY WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, COURSE OF DEALING, USAGE OF TRADE, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING, REPRODUCING, MODIFYING, PERFORMING, DISPLAYING OR DISTRIBUTING ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND ASSUME ANY AND ALL RISKS ASSOCIATED WITH YOUR OR A THIRD PARTY’S USE OR DISTRIBUTION OF ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND YOUR EXERCISE OF RIGHTS AND PERMISSIONS UNDER THIS AGREEMENT.
+c. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL TENCENT OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, FOR ANY DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, CONSEQUENTIAL OR PUNITIVE DAMAGES, OR LOST PROFITS OF ANY KIND ARISING FROM THIS AGREEMENT OR RELATED TO ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS, EVEN IF TENCENT OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING.
+8. SURVIVAL AND TERMINATION.
+a. The term of this Agreement shall commence upon Your acceptance of this Agreement or access to the Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein.
+b. We may terminate this Agreement if You breach any of the terms or conditions of this Agreement. Upon termination of this Agreement, You must promptly delete and cease use of the Tencent Hunyuan 3D 2.1 Works. Sections 6(a), 6(c), 7 and 9 shall survive the termination of this Agreement.
+9. GOVERNING LAW AND JURISDICTION.
+a. This Agreement and any dispute arising out of or relating to it will be governed by the laws of the Hong Kong Special Administrative Region of the People’s Republic of China, without regard to conflict of law principles, and the UN Convention on Contracts for the International Sale of Goods does not apply to this Agreement.
+b. Exclusive jurisdiction and venue for any dispute arising out of or relating to this Agreement will be a court of competent jurisdiction in the Hong Kong Special Administrative Region of the People’s Republic of China, and Tencent and Licensee consent to the exclusive jurisdiction of such court with respect to any such dispute.
+
+EXHIBIT A
+ACCEPTABLE USE POLICY
+
+Tencent reserves the right to update this Acceptable Use Policy from time to time.
+Last modified: November 5, 2024
+
+Tencent endeavors to promote safe and fair use of its tools and features, including Tencent Hunyuan 3D 2.1. You agree not to use Tencent Hunyuan 3D 2.1 or Model Derivatives:
+1. Outside the Territory;
+2. In any way that violates any applicable national, federal, state, local, international or any other law or regulation;
+3. To harm Yourself or others;
+4. To repurpose or distribute output from Tencent Hunyuan 3D 2.1 or any Model Derivatives to harm Yourself or others;
+5. To override or circumvent the safety guardrails and safeguards We have put in place;
+6. For the purpose of exploiting, harming or attempting to exploit or harm minors in any way;
+7. To generate or disseminate verifiably false information and/or content with the purpose of harming others or influencing elections;
+8. To generate or facilitate false online engagement, including fake reviews and other means of fake online engagement;
+9. To intentionally defame, disparage or otherwise harass others;
+10. To generate and/or disseminate malware (including ransomware) or any other content to be used for the purpose of harming electronic systems;
+11. To generate or disseminate personal identifiable information with the purpose of harming others;
+12. To generate or disseminate information (including images, code, posts, articles), and place the information in any public context (including –through the use of bot generated tweets), without expressly and conspicuously identifying that the information and/or content is machine generated;
+13. To impersonate another individual without consent, authorization, or legal right;
+14. To make high-stakes automated decisions in domains that affect an individual’s safety, rights or wellbeing (e.g., law enforcement, migration, medicine/health, management of critical infrastructure, safety components of products, essential services, credit, employment, housing, education, social scoring, or insurance);
+15. In a manner that violates or disrespects the social ethics and moral standards of other countries or regions;
+16. To perform, facilitate, threaten, incite, plan, promote or encourage violent extremism or terrorism;
+17. For any use intended to discriminate against or harm individuals or groups based on protected characteristics or categories, online or offline social behavior or known or predicted personal or personality characteristics;
+18. To intentionally exploit any of the vulnerabilities of a specific group of persons based on their age, social, physical or mental characteristics, in order to materially distort the behavior of a person pertaining to that group in a manner that causes or is likely to cause that person or another person physical or psychological harm;
+19. For military purposes;
+20. To engage in the unauthorized or unlicensed practice of any profession including, but not limited to, financial, legal, medical/health, or other professional practices.
diff --git a/Hunyuan3D-2.1/README.md b/Hunyuan3D-2.1/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ee0b2f1dd24458287629d7fc06743204b8cc7bb2
--- /dev/null
+++ b/Hunyuan3D-2.1/README.md
@@ -0,0 +1,199 @@
+---
+title: Hunyuan3D-2.1
+emoji: 👻
+colorFrom: red
+colorTo: green
+sdk: gradio
+sdk_version: 4.44.0
+
+app_file: gradio_app.py
+pinned: false
+short_description: Image-to-3D Generation
+---
+
+
+
+
+
+
+
+
+
+[//]: # ( )
+
+[//]: # ( )
+
+[//]: # ( )
+
+
+## 🔥 News
+
+- Jun 19, 2025: 👋 We present the [technical report](https://arxiv.org/abs/2506.15442) of Hunyuan3D-2.1, please check out the details and spark some discussion!
+- Jun 13, 2025: 🤗 We release the first production-ready 3D asset generation model, Hunyuan3D-2.1!
+
+> Join our **[Wechat](#)** and **[Discord](https://discord.gg/dNBrdrGGMa)** group to discuss and find help from us.
+
+| Wechat Group | Xiaohongshu | X | Discord |
+|--------------------------------------------------|-------------------------------------------------------|---------------------------------------------|---------------------------------------------------|
+| | | | |
+
+
+
+## ☯️ **Hunyuan3D 2.1**
+
+### Architecture
+
+Tencent Hunyuan3D-2.1 is a scalable 3D asset creation system that advances state-of-the-art 3D generation through two pivotal innovations: Fully Open-Source Framework and Physically-Based Rendering (PBR) Texture Synthesis. For the first time, the system releases full model weights and training code, enabling community developers to directly fine-tune and extend the model for diverse downstream applications. This transparency accelerates academic research and industrial deployment. Moreover, replacing the prior RGB-based texture model, the upgraded PBR pipeline leverages physics-grounded material simulation to generate textures with photorealistic light interaction (e.g., metallic reflections, subsurface scattering).
+
+
+
+
+
+### Performance
+
+We have evaluated Hunyuan3D 2.1 with other open-source as well as close-source 3d-generation methods.
+The numerical results indicate that Hunyuan3D 2.1 surpasses all baselines in the quality of generated textured 3D assets
+and the condition following ability.
+
+| Model | ULIP-T(⬆) | ULIP-I(⬆) | Uni3D-T(⬆) | Uni3D-I(⬆) |
+|-------------------------|-----------|-------------|-------------|---------------|
+| Michelangelo | 0.0752 | 0.1152 | 0.2133 | 0.2611 |
+| Craftsman | 0.0745 | 0.1296 | 0.2375 | 0.2987 |
+| TripoSG | 0.0767 | 0.1225 | 0.2506 | 0.3129 |
+| Step1X-3D | 0.0735 | 0.1183 | 0.2554 | 0.3195 |
+| Trellis | 0.0769 | 0.1267 | 0.2496 | 0.3116 |
+| Direct3D-S2 | 0.0706 | 0.1134 | 0.2346 | 0.2930 |
+| Hunyuan3D-Shape-2.1 | **0.0774** | **0.1395** | **0.2556** | **0.3213** |
+
+
+| Model | CLIP-FiD(⬇) | CMMD(⬇) | CLIP-I(⬆) | LPIPS(⬇) |
+|-------------------------|-----------|-------------|-------------|---------------|
+| SyncMVD-IPA | 28.39 | 2.397 | 0.8823 | 0.1423 |
+| TexGen | 28.24 | 2.448 | 0.8818 | 0.1331 |
+| Hunyuan3D-2.0 | 26.44 | 2.318 | 0.8893 | 0.1261 |
+| Hunyuan3D-Paint-2.1 | **24.78** | **2.191** | **0.9207** | **0.1211** |
+
+
+
+## 🎁 Models Zoo
+
+It takes 10 GB VRAM for shape generation, 21GB for texture generation and 29GB for shape and texture generation in total.
+
+
+| Model | Description | Date | Size | Huggingface |
+|----------------------------|-----------------------------|------------|------|-------------------------------------------------------------------------------------------|
+| Hunyuan3D-Shape-v2-1 | Image to Shape Model | 2025-06-14 | 3.3B | [Download](https://huggingface.co/tencent/Hunyuan3D-2.1/tree/main/hunyuan3d-dit-v2-1) |
+| Hunyuan3D-Paint-v2-1 | Texture Generation Model | 2025-06-14 | 2B | [Download](https://huggingface.co/tencent/Hunyuan3D-2.1/tree/main/hunyuan3d-paint-v2-1) |
+
+
+## 🤗 Get Started with Hunyuan3D 2.1
+
+Hunyuan3D 2.1 supports Macos, Windows, Linux. You may follow the next steps to use Hunyuan3D 2.1 via:
+
+### Install Requirements
+We test our model on an A100 GPU with Python 3.10 and PyTorch 2.5.1+cu124.
+```bash
+pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu124
+pip install -r requirements.txt
+
+cd hy3dpaint/custom_rasterizer
+pip install -e .
+cd ../..
+cd hy3dpaint/DifferentiableRenderer
+bash compile_mesh_painter.sh
+cd ../..
+```
+
+### Code Usage
+
+We designed a diffusers-like API to use our shape generation model - Hunyuan3D-Shape and texture synthesis model -
+Hunyuan3D-Paint.
+
+```python
+import sys
+sys.path.insert(0, './hy3dshape')
+sys.path.insert(0, './hy3dpaint')
+from textureGenPipeline import Hunyuan3DPaintPipeline
+from textureGenPipeline import Hunyuan3DPaintPipeline, Hunyuan3DPaintConfig
+
+# let's generate a mesh first
+shape_pipeline = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained('tencent/Hunyuan3D-2.1')
+mesh_untextured = shape_pipeline(image='assets/demo.png')[0]
+
+paint_pipeline = Hunyuan3DPaintPipeline(Hunyuan3DPaintConfig(max_num_view=6, resolution=512))
+mesh_textured = paint_pipeline(mesh_path, image_path='assets/demo.png')
+```
+
+
+### Gradio App
+
+You could also host a [Gradio](https://www.gradio.app/) App in your own computer via:
+
+
+```bash
+python3 gradio_app.py \
+ --model_path tencent/Hunyuan3D-2.1 \
+ --subfolder hunyuan3d-dit-v2-1 \
+ --texgen_model_path tencent/Hunyuan3D-2.1 \
+ --low_vram_mode
+```
+
+
+## 🔗 BibTeX
+
+If you found this repository helpful, please cite our reports:
+
+```bibtex
+@misc{hunyuan3d2025hunyuan3d,
+ title={Hunyuan3D 2.1: From Images to High-Fidelity 3D Assets with Production-Ready PBR Material},
+ author={Team Hunyuan3D and Shuhui Yang and Mingxin Yang and Yifei Feng and Xin Huang and Sheng Zhang and Zebin He and Di Luo and Haolin Liu and Yunfei Zhao and Qingxiang Lin and Zeqiang Lai and Xianghui Yang and Huiwen Shi and Zibo Zhao and Bowen Zhang and Hongyu Yan and Lifu Wang and Sicong Liu and Jihong Zhang and Meng Chen and Liang Dong and Yiwen Jia and Yulin Cai and Jiaao Yu and Yixuan Tang and Dongyuan Guo and Junlin Yu and Hao Zhang and Zheng Ye and Peng He and Runzhou Wu and Shida Wei and Chao Zhang and Yonghao Tan and Yifu Sun and Lin Niu and Shirui Huang and Bojian Zheng and Shu Liu and Shilin Chen and Xiang Yuan and Xiaofeng Yang and Kai Liu and Jianchen Zhu and Peng Chen and Tian Liu and Di Wang and Yuhong Liu and Linus and Jie Jiang and Jingwei Huang and Chunchao Guo},
+ year={2025},
+ eprint={2506.15442},
+ archivePrefix={arXiv},
+ primaryClass={cs.CV}
+}
+
+@misc{hunyuan3d22025tencent,
+ title={Hunyuan3D 2.0: Scaling Diffusion Models for High Resolution Textured 3D Assets Generation},
+ author={Tencent Hunyuan3D Team},
+ year={2025},
+ eprint={2501.12202},
+ archivePrefix={arXiv},
+ primaryClass={cs.CV}
+}
+
+@misc{yang2024hunyuan3d,
+ title={Hunyuan3D 1.0: A Unified Framework for Text-to-3D and Image-to-3D Generation},
+ author={Tencent Hunyuan3D Team},
+ year={2024},
+ eprint={2411.02293},
+ archivePrefix={arXiv},
+ primaryClass={cs.CV}
+}
+```
+
+## Acknowledgements
+
+We would like to thank the contributors to
+the [TripoSG](https://github.com/VAST-AI-Research/TripoSG), [Trellis](https://github.com/microsoft/TRELLIS), [DINOv2](https://github.com/facebookresearch/dinov2), [Stable Diffusion](https://github.com/Stability-AI/stablediffusion), [FLUX](https://github.com/black-forest-labs/flux), [diffusers](https://github.com/huggingface/diffusers), [HuggingFace](https://huggingface.co), [CraftsMan3D](https://github.com/wyysf-98/CraftsMan3D),
+and [Michelangelo](https://github.com/NeuralCarver/Michelangelo/tree/main) repositories, for their open research and
+exploration.
+
+## Star History
+
+
+
+
+
+
+
+
diff --git a/Hunyuan3D-2.1/assets/demo.png b/Hunyuan3D-2.1/assets/demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c069409fe6c9b91e68ddaf13a049bab61a1523d
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/demo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4260b9a45c39fc4045bae81d27f8eb17127cdb201df614193077268d996ce436
+size 151014
diff --git a/Hunyuan3D-2.1/assets/env_maps/gradient.jpg b/Hunyuan3D-2.1/assets/env_maps/gradient.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..55546c1f260daa7d3c6eef36b70fe5d7e1697df0
Binary files /dev/null and b/Hunyuan3D-2.1/assets/env_maps/gradient.jpg differ
diff --git a/Hunyuan3D-2.1/assets/env_maps/white.jpg b/Hunyuan3D-2.1/assets/env_maps/white.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f7af1237608dd1d486edb9298c04fbe15ec74185
Binary files /dev/null and b/Hunyuan3D-2.1/assets/env_maps/white.jpg differ
diff --git a/Hunyuan3D-2.1/assets/example_images/1204.png b/Hunyuan3D-2.1/assets/example_images/1204.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c5e833bdfacb030f8673d07c17089896d812057
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/1204.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0620e8189232a5a553975aa9f544a5c09097154d3f8457e25917876a27af4ff0
+size 469722
diff --git a/Hunyuan3D-2.1/assets/example_images/1627.png b/Hunyuan3D-2.1/assets/example_images/1627.png
new file mode 100644
index 0000000000000000000000000000000000000000..05c4fbb2970296f10d114a3705cfc7691042f5bf
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/1627.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6de52ff9e95ac9ab7a3f0b6016dc8aa204babc6edab0f506d085a0116551d2c4
+size 269408
diff --git a/Hunyuan3D-2.1/assets/example_images/219.png b/Hunyuan3D-2.1/assets/example_images/219.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac2036ce8202e477f1fdd6bdd9588f95961ec8d3
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/219.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3db54f848d703032f9d3c0c5bb9c8a0fea8bfa03b263d5b5dcf7f9fc738e4be3
+size 164817
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g0k031h3nikcok2105nmanksg8l5pbbr7bqo.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g0k031h3nikcok2105nmanksg8l5pbbr7bqo.png
new file mode 100644
index 0000000000000000000000000000000000000000..11823eb9ff911b9f80e4174fb646a79bd41dc9b9
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g0k031h3nikcok2105nmanksg8l5pbbr7bqo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb67a18a5d7c959278be3a13f75ed50c641c4b1f9bba7bf82d62de9e41fa1ac2
+size 1428029
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmm0kqa42405np612cg9dc6aqccf38.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmm0kqa42405np612cg9dc6aqccf38.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f1885ac58ed5e9e982296ae60458890b250abc5
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmm0kqa42405np612cg9dc6aqccf38.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f36a75190e611195fe18e18b40fb6207cae672b7736c09ae99e1ab190f88d417
+size 1081753
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmv1te73a3048jtdvj4c5rbhtrtu98.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmv1te73a3048jtdvj4c5rbhtrtu98.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0512a6d11236151862babc13d22cc16c306e88e
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hmv1te73a3048jtdvj4c5rbhtrtu98.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d15ab9a53b4895d73a2b6ea31314d6c4078f6bb32f31219e5b9a80f9f45a93d5
+size 1259694
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hnup72ck24g5nue8l108b6nb88hkf8.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hnup72ck24g5nue8l108b6nb88hkf8.png
new file mode 100644
index 0000000000000000000000000000000000000000..376367e05f50dcb1cb6b28754a6a3142044d4c80
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hnup72ck24g5nue8l108b6nb88hkf8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bed4bed1a4fcfaa2cb702aa50322760e2fb86d85b7718edbe6175450d9c731e7
+size 2291497
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hoft434340g5og0ja2oco7h0k4l5ro.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hoft434340g5og0ja2oco7h0k4l5ro.png
new file mode 100644
index 0000000000000000000000000000000000000000..e83415ad094380c8ea858b628c378d26004b0cf9
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g34o31hoft434340g5og0ja2oco7h0k4l5ro.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b7ef7e57fe508bf26559f1e152d717c1963d73ee82672ddcb23b65745673aa59
+size 889588
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k031hitndtdk2605orjhoonrn9pgo7vls0.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k031hitndtdk2605orjhoonrn9pgo7vls0.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ce7a377e15920ece2cdecef9ec5941f7b02470a
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k031hitndtdk2605orjhoonrn9pgo7vls0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:29574317912dcccbeb1dcf1e4126417a2162ea8a307969b03f8e73edcbb694b4
+size 2669422
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831ho6lsmo3ujg5pf2trqjcqh7vvmb00g.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831ho6lsmo3ujg5pf2trqjcqh7vvmb00g.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a866604dc71e50a3cb1f0369610e0057b30eb2e
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831ho6lsmo3ujg5pf2trqjcqh7vvmb00g.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:35730e5ded784695b13512b471f28a7ed8c819e09f691003658120d291a558d5
+size 954014
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hp7srtcjoe05nihqp1g8rq0th69ncg.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hp7srtcjoe05nihqp1g8rq0th69ncg.png
new file mode 100644
index 0000000000000000000000000000000000000000..787576f559441b6510f01bfb5af933a87432b994
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hp7srtcjoe05nihqp1g8rq0th69ncg.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:263e083e800ee43ad781d8c3fbab37773bba5363821b35616a88fa41819a1a4a
+size 1532920
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hpb3dlt3idg5nr0msu0907jusb30n8.png b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hpb3dlt3idg5nr0msu0907jusb30n8.png
new file mode 100644
index 0000000000000000000000000000000000000000..8caee7f712c87675c6eaa456a1fedbbed5e7c39c
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_1040g3k831hpb3dlt3idg5nr0msu0907jusb30n8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d785e9558ba5418679a5bb1586e6e81160111dadc1d4f8df24371b41edafb9a8
+size 1233930
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220925801040g00831gddt2hh3a4g4a11mgjsgcu8r915tdg.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220925801040g00831gddt2hh3a4g4a11mgjsgcu8r915tdg.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5ac89f13455360173d1c17a35062c1ffc8e7d1f
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220925801040g00831gddt2hh3a4g4a11mgjsgcu8r915tdg.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:666d5542f64374594bb62bd3c589f4354157b673929555e62f2386b7bac518f5
+size 673822
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220948541040g00831gddt2hh3a604a11mgjsgcu87ec4kd0.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220948541040g00831gddt2hh3a604a11mgjsgcu87ec4kd0.png
new file mode 100644
index 0000000000000000000000000000000000000000..30b740ae41b4d285e1283a21731dcdeac6889980
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459220948541040g00831gddt2hh3a604a11mgjsgcu87ec4kd0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a297dda51c69a848cd6b902feed5755b34a26e0d9fa4e8cc665ecdb74622319
+size 644726
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459234709671040g00831g0tg76cge6g5n2g1pd4m8g1ijr22c8.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459234709671040g00831g0tg76cge6g5n2g1pd4m8g1ijr22c8.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea844c7cb292edbd82977a5d65e2c7d3b2e729fb
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17459234709671040g00831g0tg76cge6g5n2g1pd4m8g1ijr22c8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:906ca9318397c1ac7e0351642de978c6771e9ad9c918b9430a5e23f5b4212a27
+size 1974399
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776897281040g2sg31gvoem3pjqeg5pvr5s839cu1ae9vono.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776897281040g2sg31gvoem3pjqeg5pvr5s839cu1ae9vono.png
new file mode 100644
index 0000000000000000000000000000000000000000..7423042a733089dfdf6a7d8b4f8cd2e89ca78d1e
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776897281040g2sg31gvoem3pjqeg5pvr5s839cu1ae9vono.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:210bc3cb580d90143c4562336804fc9b7c7c1328ac0347706d5bee0786fab2e4
+size 1098032
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776916821040g2sg31gvoem3pjqf05pvr5s839cu1pkdjmf8.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776916821040g2sg31gvoem3pjqf05pvr5s839cu1pkdjmf8.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fc53e75c35109a3e3bda4538d8b85f4a5db3b3c
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17461776916821040g2sg31gvoem3pjqf05pvr5s839cu1pkdjmf8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e48f334038708fd45b31f86c1af0b5f5a1d368febf995e128a868baa2bdef475
+size 1162386
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17478460238811040g00831hoen1ga3u0g5oha0d441i3j1s6i7eo.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17478460238811040g00831hoen1ga3u0g5oha0d441i3j1s6i7eo.png
new file mode 100644
index 0000000000000000000000000000000000000000..4940c95a71183054e48cca869315c34801656dee
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17478460238811040g00831hoen1ga3u0g5oha0d441i3j1s6i7eo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d2119327fb92ccb3ccbb59f0bbc15ed49ae64f0a06998c2316e6f20f89de91c9
+size 1245063
diff --git a/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17480136679411040g00831hn2tbsojucg5pl27pu7c1mcgk10jug.png b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17480136679411040g00831hn2tbsojucg5pl27pu7c1mcgk10jug.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc46afcb29e3303560fc4adeba4c33de6383259c
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/Camera_XHS_17480136679411040g00831hn2tbsojucg5pl27pu7c1mcgk10jug.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:66d523e4d964a155e7539748e340a0c5f385c3055dc2c57871b1dcaa227ccf38
+size 669697
diff --git a/Hunyuan3D-2.1/assets/example_images/ainimal_14.png b/Hunyuan3D-2.1/assets/example_images/ainimal_14.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b9eab08f12403920f5c9b1c6b9005383ae1ee4e
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/ainimal_14.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:17baf5964a354720de15050d1d5f78d5a9a7ac40b853241dac35173b77dad236
+size 1190444
diff --git a/Hunyuan3D-2.1/assets/example_images/ainimal_17.png b/Hunyuan3D-2.1/assets/example_images/ainimal_17.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1569fc5a43d261eb3cbe02d3ab9ec75f5855c91
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/ainimal_17.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:993d1487cc928fe640f570934a136f6c5ff1cc30f6c7eb1b8687bebbb26c62b2
+size 898854
diff --git a/Hunyuan3D-2.1/assets/example_images/ainimal_21.png b/Hunyuan3D-2.1/assets/example_images/ainimal_21.png
new file mode 100644
index 0000000000000000000000000000000000000000..8209074e699f3add0458ca4cbcffb2014516ec53
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/ainimal_21.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:22b5eabda71b395879e3ec428a097cdbd1bae645d329a0aefef90bcdfbf7acdc
+size 897465
diff --git a/Hunyuan3D-2.1/assets/example_images/ainimal_9.png b/Hunyuan3D-2.1/assets/example_images/ainimal_9.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ebfc0191f8fa13bf2e08369966b6b32fb62a15a
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/ainimal_9.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:83e7a3f6d8ab2015fe3a6a14ce295cd9bcb612141fde88e19a1613aee965405c
+size 855446
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng1.png b/Hunyuan3D-2.1/assets/example_images/jimeng1.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6bcd15036155918e746938f1d15fd7c6deef742
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng1.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8c7ec612c33084bfd97729ab0ed8607c40d443c8ac6adcf728bd7db73ba818ab
+size 975449
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng11.png b/Hunyuan3D-2.1/assets/example_images/jimeng11.png
new file mode 100644
index 0000000000000000000000000000000000000000..3633c75f44a5ca6624c1438dccd876c5611e9e79
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng11.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05e2828d11fdf80e435d6df787d846ae8703d9b7718069c0809a436ddbe8abf1
+size 828010
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng14.png b/Hunyuan3D-2.1/assets/example_images/jimeng14.png
new file mode 100644
index 0000000000000000000000000000000000000000..3912701c5409b4a5bd3ebed309cc939643f7de77
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng14.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb0cc5781d0156822f7b2298ff974b38d769aee500975523a83e7b55524dfb7b
+size 814651
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng16.png b/Hunyuan3D-2.1/assets/example_images/jimeng16.png
new file mode 100644
index 0000000000000000000000000000000000000000..8013fac8e8c1dda49debd62eb527d29e83350764
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng16.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:14c1cd3b74da39fb43a753d95d6cc72b7b296cda7e99ffcb3d573a1e8d3f0666
+size 644574
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng18.png b/Hunyuan3D-2.1/assets/example_images/jimeng18.png
new file mode 100644
index 0000000000000000000000000000000000000000..33d24e8e9ea644516a7e6a0a73d130bb9015bff4
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng18.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fab385e0f35e192b1691be4f34292d1e62a5ef210e6120ae78dad66b06da1653
+size 1726665
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng2.png b/Hunyuan3D-2.1/assets/example_images/jimeng2.png
new file mode 100644
index 0000000000000000000000000000000000000000..48a2d4fcbf40a238c3fde03e4626d37134aaf56d
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng2.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f56e77e149d2c920f5eb627ff9a560c4ce99d4581c96da8319f848c023c773bf
+size 1182016
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng20.png b/Hunyuan3D-2.1/assets/example_images/jimeng20.png
new file mode 100644
index 0000000000000000000000000000000000000000..95576f8c75c4b5cd5b7af987727492c5a44cfe9d
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng20.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:60384476dcda22a10afca1d25c99f3edaf6f5e6181c36bff52239e997f7612eb
+size 1384458
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng22.png b/Hunyuan3D-2.1/assets/example_images/jimeng22.png
new file mode 100644
index 0000000000000000000000000000000000000000..c44c2c2823a34bb527cba9c39dbb2ebeb74330d2
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng22.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f6d77f8aef3cbeadb039e7ea5d7e7c96cf219ec1248b7d0b3529cd3a0d926949
+size 932253
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng37.png b/Hunyuan3D-2.1/assets/example_images/jimeng37.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee9e1cacc2174a8eda2913ca2d431bb0610f4f3b
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng37.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8641b72c15f51607e810e446ff9c5bebf4a17493b29d4d498818e8d6fffa912
+size 1152064
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng42.png b/Hunyuan3D-2.1/assets/example_images/jimeng42.png
new file mode 100644
index 0000000000000000000000000000000000000000..86d6550dd58d2f2a7ef7784a3204a381fb9a4a71
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng42.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:97f268f0bcb3486a419893b4ed83f0778a4fd476819898f640cd8cec5d62874e
+size 1249285
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng43.png b/Hunyuan3D-2.1/assets/example_images/jimeng43.png
new file mode 100644
index 0000000000000000000000000000000000000000..632c4539ebd1b2649a8dd61242a5af82277eb445
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng43.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3e3e1401347ff8f925ac6c5ac55c4cedc806a14e8c7d9012378b5e2860f3e877
+size 1095611
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng44.png b/Hunyuan3D-2.1/assets/example_images/jimeng44.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1bff43f4a4378cec1f008e996ee8f44698f8f84
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng44.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5d100b799b7a55ee7e5af94f9ba6ce0fd8389925ee0bab7f937a83eae83c69d0
+size 916914
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng54.png b/Hunyuan3D-2.1/assets/example_images/jimeng54.png
new file mode 100644
index 0000000000000000000000000000000000000000..aadbbe234aded692c0301c095df4946f696997c8
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng54.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:863eff859137723cd5f2e7a3d594c7b92b7e36228286f63153a548d16cb0b318
+size 739245
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng6.png b/Hunyuan3D-2.1/assets/example_images/jimeng6.png
new file mode 100644
index 0000000000000000000000000000000000000000..042309b2d0e3abaa1ceb0e13ac00ba48ef42d596
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3a7b85d10c11f7e4c7de1b00351566ac22b81b6051eeac61a065d8adf0907d0b
+size 541571
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng63.png b/Hunyuan3D-2.1/assets/example_images/jimeng63.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bebd5699bf023019f08f88700e6868b42da8d29
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng63.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:176b4f99ffe3c63a243cf271adc8d54b6a4f062d046588adb40c5f18c255b1f1
+size 786983
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng64.png b/Hunyuan3D-2.1/assets/example_images/jimeng64.png
new file mode 100644
index 0000000000000000000000000000000000000000..d565d779a4d12b5ffab327937f980e19d608b1ca
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng64.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:544d3125ea27a1e3653120c5610d62ec7c0c402517656f07d5737d776639793a
+size 166306
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng65.png b/Hunyuan3D-2.1/assets/example_images/jimeng65.png
new file mode 100644
index 0000000000000000000000000000000000000000..531e58fe8e7654f70605905ce91d1a1db99600e7
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng65.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3fd9004529c6cab14b0aa97e04ad32317a7e1b7ff3ff395ad4c656473e63eae1
+size 204019
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng75.png b/Hunyuan3D-2.1/assets/example_images/jimeng75.png
new file mode 100644
index 0000000000000000000000000000000000000000..591ae7896b96864504b0dc5c3443b2cc901729f8
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng75.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18d74eb96a565497c1aa8498db3bd9b0c4cb17df0a153d65ca580a5b0f47a1fa
+size 187736
diff --git a/Hunyuan3D-2.1/assets/example_images/jimeng82.png b/Hunyuan3D-2.1/assets/example_images/jimeng82.png
new file mode 100644
index 0000000000000000000000000000000000000000..7555220b259385eebcaac60f5d32690a91078705
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/jimeng82.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0c0e8aeb54d53dc7638be4366d0f9fb0ed8b98132f58622179d501192c807458
+size 204526
diff --git a/Hunyuan3D-2.1/assets/example_images/kaijia_qie.png b/Hunyuan3D-2.1/assets/example_images/kaijia_qie.png
new file mode 100644
index 0000000000000000000000000000000000000000..25cfd39bf240a1127af0d6d2b65b0675c2f52aec
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/kaijia_qie.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:efc6b09d6b421ed3bc54bc89e59fb71feda7b99153867eb1dfb11db68c73524c
+size 863388
diff --git a/Hunyuan3D-2.1/assets/example_images/mmexport02df348f675e40d6e3828fae4cb8f2b3_1746117674020.png b/Hunyuan3D-2.1/assets/example_images/mmexport02df348f675e40d6e3828fae4cb8f2b3_1746117674020.png
new file mode 100644
index 0000000000000000000000000000000000000000..29d13ff8b41d5703a6356c49a1767e8a3ed93cfa
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/mmexport02df348f675e40d6e3828fae4cb8f2b3_1746117674020.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d10cf9c1f40ac325580cf0a1e1a8dd69ee74ff6d2e92d0c5e86a13b6af47f30b
+size 1173380
diff --git a/Hunyuan3D-2.1/assets/example_images/mmexportde235211f304fd83ec9d60e38c9f6f0b_1747975667632.png b/Hunyuan3D-2.1/assets/example_images/mmexportde235211f304fd83ec9d60e38c9f6f0b_1747975667632.png
new file mode 100644
index 0000000000000000000000000000000000000000..a307712d3fcea42440902517625ee86c725758f1
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/mmexportde235211f304fd83ec9d60e38c9f6f0b_1747975667632.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dabfeedee6b970cd9a284c100905de3973bf8aad0810e907907340a7b0d777b9
+size 1408097
diff --git a/Hunyuan3D-2.1/assets/example_images/qie.png b/Hunyuan3D-2.1/assets/example_images/qie.png
new file mode 100644
index 0000000000000000000000000000000000000000..47f8ac7e82610c7432e05adea02d615eb764883d
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_images/qie.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7989cf366180af5beaece53fffc6ec3a48c07822663c978714e975c50ea019e1
+size 1070463
diff --git a/Hunyuan3D-2.1/assets/example_prompts.txt b/Hunyuan3D-2.1/assets/example_prompts.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51550223aa081074d221a086ff76ff8ce2245c40
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/example_prompts.txt
@@ -0,0 +1,5 @@
+一片绿色的树叶在白色背景上居中展现,清晰的纹理
+一只棕白相间的仓鼠,站在白色背景前。照片采用居中构图方式,卡通风格
+一盆绿色植物生长在红色花盆中,居中,写实
+a pot of green plants grows in a red flower pot.
+a lovely rabbit eating carrots
diff --git a/Hunyuan3D-2.1/assets/images/pipeline.png b/Hunyuan3D-2.1/assets/images/pipeline.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bf4df8486db15eb13d2adbd4386c19a7f4614ab
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/images/pipeline.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e79eb1f230118d93c495ac45d2bf4ff2d9a6021c5accb31992c82614f21c55dd
+size 5050594
diff --git a/Hunyuan3D-2.1/assets/images/teaser.jpg b/Hunyuan3D-2.1/assets/images/teaser.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a4763cddfe2e02b99147365d423a3f59661906c0
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/images/teaser.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6576dadddc3a712ed836a1059175765b81426243f1d0293851dfb271e45de6ee
+size 1803414
diff --git a/Hunyuan3D-2.1/assets/modelviewer-template.html b/Hunyuan3D-2.1/assets/modelviewer-template.html
new file mode 100644
index 0000000000000000000000000000000000000000..3406cb1950b03172b6836cbc66be37da5d654aa5
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/modelviewer-template.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/assets/modelviewer-textured-template.html b/Hunyuan3D-2.1/assets/modelviewer-textured-template.html
new file mode 100644
index 0000000000000000000000000000000000000000..6785124bc409bde2689885baaf45e89675a51e00
--- /dev/null
+++ b/Hunyuan3D-2.1/assets/modelviewer-textured-template.html
@@ -0,0 +1,321 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/assets/qrcode/discord.png b/Hunyuan3D-2.1/assets/qrcode/discord.png
new file mode 100644
index 0000000000000000000000000000000000000000..a9c326d016c9520980845705526f1779feb362a7
Binary files /dev/null and b/Hunyuan3D-2.1/assets/qrcode/discord.png differ
diff --git a/Hunyuan3D-2.1/assets/qrcode/wechat.png b/Hunyuan3D-2.1/assets/qrcode/wechat.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f25092d07ee612ff4ef82d4afd41acfca293f3c
Binary files /dev/null and b/Hunyuan3D-2.1/assets/qrcode/wechat.png differ
diff --git a/Hunyuan3D-2.1/assets/qrcode/x.png b/Hunyuan3D-2.1/assets/qrcode/x.png
new file mode 100644
index 0000000000000000000000000000000000000000..e9f9044864143265d9b9da8883c4ee83da2f8c0b
Binary files /dev/null and b/Hunyuan3D-2.1/assets/qrcode/x.png differ
diff --git a/Hunyuan3D-2.1/assets/qrcode/xiaohongshu.png b/Hunyuan3D-2.1/assets/qrcode/xiaohongshu.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ace644a12f01967c27d7126c4eedde71e99e1ac
Binary files /dev/null and b/Hunyuan3D-2.1/assets/qrcode/xiaohongshu.png differ
diff --git a/Hunyuan3D-2.1/custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl b/Hunyuan3D-2.1/custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl
new file mode 100644
index 0000000000000000000000000000000000000000..6e89203c1a1f2da8f7118eb475f9ea58c6b24059
--- /dev/null
+++ b/Hunyuan3D-2.1/custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4fa9b61d3bafd3f1d5eedd200c4d74c54cfbad8da6cd1cfc1218cecf601a682d
+size 4860060
diff --git a/Hunyuan3D-2.1/demo.py b/Hunyuan3D-2.1/demo.py
new file mode 100644
index 0000000000000000000000000000000000000000..6f0bf9a272a705329ccc640bd2097b2827e90af9
--- /dev/null
+++ b/Hunyuan3D-2.1/demo.py
@@ -0,0 +1,45 @@
+import sys
+sys.path.insert(0, './hy3dshape')
+sys.path.insert(0, './hy3dpaint')
+
+from PIL import Image
+from hy3dshape.rembg import BackgroundRemover
+from hy3dshape.pipelines import Hunyuan3DDiTFlowMatchingPipeline
+from textureGenPipeline import Hunyuan3DPaintPipeline, Hunyuan3DPaintConfig
+
+try:
+ from torchvision_fix import apply_fix
+ apply_fix()
+except ImportError:
+ print("Warning: torchvision_fix module not found, proceeding without compatibility fix")
+except Exception as e:
+ print(f"Warning: Failed to apply torchvision fix: {e}")
+
+# shape
+model_path = 'tencent/Hunyuan3D-2.1'
+pipeline_shapegen = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained(model_path)
+
+image_path = 'assets/demo.png'
+image = Image.open(image_path).convert("RGBA")
+if image.mode == 'RGB':
+ rembg = BackgroundRemover()
+ image = rembg(image)
+
+mesh = pipeline_shapegen(image=image)[0]
+mesh.export('demo.glb')
+
+# paint
+max_num_view = 6 # can be 6 to 9
+resolution = 512 # can be 768 or 512
+conf = Hunyuan3DPaintConfig(max_num_view, resolution)
+conf.realesrgan_ckpt_path = "hy3dpaint/ckpt/RealESRGAN_x4plus.pth"
+conf.multiview_cfg_path = "hy3dpaint/cfgs/hunyuan-paint-pbr.yaml"
+conf.custom_pipeline = "hy3dpaint/hunyuanpaintpbr"
+paint_pipeline = Hunyuan3DPaintPipeline(conf)
+
+output_mesh_path = 'demo_textured.glb'
+output_mesh_path = paint_pipeline(
+ mesh_path = "demo.glb",
+ image_path = 'assets/demo.png',
+ output_mesh_path = output_mesh_path
+)
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/gradio_app.py b/Hunyuan3D-2.1/gradio_app.py
new file mode 100644
index 0000000000000000000000000000000000000000..46b999ac072f3e4523a073ec633473d5c7ef400a
--- /dev/null
+++ b/Hunyuan3D-2.1/gradio_app.py
@@ -0,0 +1,927 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+# Apply torchvision compatibility fix before other imports
+
+import sys
+sys.path.insert(0, './hy3dshape')
+sys.path.insert(0, './hy3dpaint')
+
+pythonpath = sys.executable
+print(pythonpath)
+
+try:
+ from torchvision_fix import apply_fix
+ apply_fix()
+except ImportError:
+ print("Warning: torchvision_fix module not found, proceeding without compatibility fix")
+except Exception as e:
+ print(f"Warning: Failed to apply torchvision fix: {e}")
+
+
+import os
+import random
+import shutil
+import subprocess
+import time
+from glob import glob
+from pathlib import Path
+
+import gradio as gr
+import torch
+import trimesh
+import uvicorn
+from fastapi import FastAPI
+from fastapi.staticfiles import StaticFiles
+import uuid
+import numpy as np
+
+from hy3dshape.utils import logger
+from hy3dpaint.convert_utils import create_glb_with_pbr_materials
+
+
+MAX_SEED = 1e7
+ENV = "Huggingface" # "Huggingface"
+if ENV == 'Huggingface':
+ """
+ Setup environment for running on Huggingface platform.
+
+ This block performs the following:
+ - Changes directory to the differentiable renderer folder and runs a shell
+ script to compile the mesh painter.
+ - Installs a custom rasterizer wheel package via pip.
+
+ Note:
+ This setup assumes the script is running in the Huggingface environment
+ with the specified directory structure.
+ """
+ import os, spaces, subprocess, sys, shlex
+ from spaces import zero
+
+ def install_cuda_toolkit():
+ # CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run"
+ CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run"
+ CUDA_TOOLKIT_FILE = "/tmp/%s" % os.path.basename(CUDA_TOOLKIT_URL)
+ subprocess.call(["wget", "-q", CUDA_TOOLKIT_URL, "-O", CUDA_TOOLKIT_FILE])
+ subprocess.call(["chmod", "+x", CUDA_TOOLKIT_FILE])
+ subprocess.call([CUDA_TOOLKIT_FILE, "--silent", "--toolkit"])
+
+ os.environ["CUDA_HOME"] = "/usr/local/cuda"
+ os.environ["PATH"] = "%s/bin:%s" % (os.environ["CUDA_HOME"], os.environ["PATH"])
+ os.environ["LD_LIBRARY_PATH"] = "%s/lib:%s" % (
+ os.environ["CUDA_HOME"],
+ "" if "LD_LIBRARY_PATH" not in os.environ else os.environ["LD_LIBRARY_PATH"],
+ )
+ # Fix: arch_list[-1] += '+PTX'; IndexError: list index out of range
+ os.environ["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6"
+
+ def prepare_env():
+ # print('install custom')
+ # os.system(f"cd /home/user/app/hy3dpaint/custom_rasterizer && {pythonpath} -m pip install -e .")
+ # os.system(f"cd /home/user/app/hy3dpaint/packages/custom_rasterizer && pip install -e .")
+ subprocess.run(shlex.split("pip install custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl"), check=True)
+
+ print("cd /home/user/app/hy3dpaint/differentiable_renderer/ && bash compile_mesh_painter.sh")
+ os.system("cd /home/user/app/hy3dpaint/DifferentiableRenderer && bash compile_mesh_painter.sh")
+ # print("wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P /home/user/app/hy3dpaint/ckpt")
+ # os.system("wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P /home/user/app/hy3dpaint/ckpt")
+
+ def check():
+ import custom_rasterizer
+ print(type(custom_rasterizer))
+ print(dir(custom_rasterizer))
+ print(getattr(custom_rasterizer, '__file__', None))
+
+ package_dir = None
+ if hasattr(custom_rasterizer, '__file__') and custom_rasterizer.__file__:
+ package_dir = os.path.dirname(custom_rasterizer.__file__)
+ elif hasattr(custom_rasterizer, '__path__'):
+ package_dir = list(custom_rasterizer.__path__)[0]
+ else:
+ raise RuntimeError("Cannot determine package path")
+ print(package_dir)
+
+ for root, dirs, files in os.walk(package_dir):
+ level = root.replace(package_dir, '').count(os.sep)
+ indent = ' ' * 4 * level
+ print(f"{indent}{os.path.basename(root)}/")
+ subindent = ' ' * 4 * (level + 1)
+ for f in files:
+ print(f"{subindent}{f}")
+
+ # print(torch.__version__)
+ # install_cuda_toolkit()
+ print(torch.__version__)
+ prepare_env()
+ check()
+
+else:
+ """
+ Define a dummy `spaces` module with a GPU decorator class for local environment.
+
+ The GPU decorator is a no-op that simply returns the decorated function unchanged.
+ This allows code that uses the `spaces.GPU` decorator to run without modification locally.
+ """
+ class spaces:
+ class GPU:
+ def __init__(self, duration=60):
+ self.duration = duration
+ def __call__(self, func):
+ return func
+
+def get_example_img_list():
+ """
+ Load and return a sorted list of example image file paths.
+
+ Searches recursively for PNG images under the './assets/example_images/' directory.
+
+ Returns:
+ list[str]: Sorted list of file paths to example PNG images.
+ """
+ print('Loading example img list ...')
+ return sorted(glob('./assets/example_images/**/*.png', recursive=True))
+
+
+def get_example_txt_list():
+ """
+ Load and return a list of example text prompts.
+
+ Reads lines from the './assets/example_prompts.txt' file, stripping whitespace.
+
+ Returns:
+ list[str]: List of example text prompts.
+ """
+ print('Loading example txt list ...')
+ txt_list = list()
+ for line in open('./assets/example_prompts.txt', encoding='utf-8'):
+ txt_list.append(line.strip())
+ return txt_list
+
+
+def gen_save_folder(max_size=200):
+ """
+ Generate a new save folder inside SAVE_DIR, maintaining a maximum number of folders.
+
+ If the number of existing folders in SAVE_DIR exceeds `max_size`, the oldest folder is removed.
+
+ Args:
+ max_size (int, optional): Maximum number of folders to keep in SAVE_DIR. Defaults to 200.
+
+ Returns:
+ str: Path to the newly created save folder.
+ """
+ os.makedirs(SAVE_DIR, exist_ok=True)
+ dirs = [f for f in Path(SAVE_DIR).iterdir() if f.is_dir()]
+ if len(dirs) >= max_size:
+ oldest_dir = min(dirs, key=lambda x: x.stat().st_ctime)
+ shutil.rmtree(oldest_dir)
+ print(f"Removed the oldest folder: {oldest_dir}")
+ new_folder = os.path.join(SAVE_DIR, str(uuid.uuid4()))
+ os.makedirs(new_folder, exist_ok=True)
+ print(f"Created new folder: {new_folder}")
+ return new_folder
+
+
+# Removed complex PBR conversion functions - using simple trimesh-based conversion
+def export_mesh(mesh, save_folder, textured=False, type='glb'):
+ """
+ Export a mesh to a file in the specified folder, optionally including textures.
+
+ Args:
+ mesh (trimesh.Trimesh): The mesh object to export.
+ save_folder (str): Directory path where the mesh file will be saved.
+ textured (bool, optional): Whether to include textures/normals in the export. Defaults to False.
+ type (str, optional): File format to export ('glb' or 'obj' supported). Defaults to 'glb'.
+
+ Returns:
+ str: The full path to the exported mesh file.
+ """
+ if textured:
+ path = os.path.join(save_folder, f'textured_mesh.{type}')
+ else:
+ path = os.path.join(save_folder, f'white_mesh.{type}')
+ if type not in ['glb', 'obj']:
+ mesh.export(path)
+ else:
+ mesh.export(path, include_normals=textured)
+ return path
+
+
+
+
+def quick_convert_with_obj2gltf(obj_path: str, glb_path: str) -> bool:
+ # 执行转换
+ textures = {
+ 'albedo': obj_path.replace('.obj', '.jpg'),
+ 'metallic': obj_path.replace('.obj', '_metallic.jpg'),
+ 'roughness': obj_path.replace('.obj', '_roughness.jpg')
+ }
+ create_glb_with_pbr_materials(obj_path, textures, glb_path)
+
+
+
+def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
+ if randomize_seed:
+ seed = random.randint(0, MAX_SEED)
+ return seed
+
+
+def build_model_viewer_html(save_folder, height=660, width=790, textured=False):
+ # Remove first folder from path to make relative path
+ if textured:
+ related_path = f"./textured_mesh.glb"
+ template_name = './assets/modelviewer-textured-template.html'
+ output_html_path = os.path.join(save_folder, f'textured_mesh.html')
+ else:
+ related_path = f"./white_mesh.glb"
+ template_name = './assets/modelviewer-template.html'
+ output_html_path = os.path.join(save_folder, f'white_mesh.html')
+ offset = 50 if textured else 10
+ with open(os.path.join(CURRENT_DIR, template_name), 'r', encoding='utf-8') as f:
+ template_html = f.read()
+
+ with open(output_html_path, 'w', encoding='utf-8') as f:
+ template_html = template_html.replace('#height#', f'{height - offset}')
+ template_html = template_html.replace('#width#', f'{width}')
+ template_html = template_html.replace('#src#', f'{related_path}/')
+ f.write(template_html)
+
+ rel_path = os.path.relpath(output_html_path, SAVE_DIR)
+ iframe_tag = f''
+ print(f'Find html file {output_html_path}, \
+{os.path.exists(output_html_path)}, relative HTML path is /static/{rel_path}')
+
+ return f"""
+
+ {iframe_tag}
+
+ """
+
+@spaces.GPU(duration=60)
+def _gen_shape(
+ caption=None,
+ image=None,
+ mv_image_front=None,
+ mv_image_back=None,
+ mv_image_left=None,
+ mv_image_right=None,
+ steps=50,
+ guidance_scale=7.5,
+ seed=1234,
+ octree_resolution=256,
+ check_box_rembg=False,
+ num_chunks=200000,
+ randomize_seed: bool = False,
+):
+ if not MV_MODE and image is None and caption is None:
+ raise gr.Error("Please provide either a caption or an image.")
+ if MV_MODE:
+ if mv_image_front is None and mv_image_back is None \
+ and mv_image_left is None and mv_image_right is None:
+ raise gr.Error("Please provide at least one view image.")
+ image = {}
+ if mv_image_front:
+ image['front'] = mv_image_front
+ if mv_image_back:
+ image['back'] = mv_image_back
+ if mv_image_left:
+ image['left'] = mv_image_left
+ if mv_image_right:
+ image['right'] = mv_image_right
+
+ seed = int(randomize_seed_fn(seed, randomize_seed))
+
+ octree_resolution = int(octree_resolution)
+ if caption: print('prompt is', caption)
+ save_folder = gen_save_folder()
+ stats = {
+ 'model': {
+ 'shapegen': f'{args.model_path}/{args.subfolder}',
+ 'texgen': f'{args.texgen_model_path}',
+ },
+ 'params': {
+ 'caption': caption,
+ 'steps': steps,
+ 'guidance_scale': guidance_scale,
+ 'seed': seed,
+ 'octree_resolution': octree_resolution,
+ 'check_box_rembg': check_box_rembg,
+ 'num_chunks': num_chunks,
+ }
+ }
+ time_meta = {}
+
+ if image is None:
+ start_time = time.time()
+ try:
+ image = t2i_worker(caption)
+ except Exception as e:
+ raise gr.Error(f"Text to 3D is disable. \
+ Please enable it by `python gradio_app.py --enable_t23d`.")
+ time_meta['text2image'] = time.time() - start_time
+
+ # remove disk io to make responding faster, uncomment at your will.
+ # image.save(os.path.join(save_folder, 'input.png'))
+ if MV_MODE:
+ start_time = time.time()
+ for k, v in image.items():
+ if check_box_rembg or v.mode == "RGB":
+ img = rmbg_worker(v.convert('RGB'))
+ image[k] = img
+ time_meta['remove background'] = time.time() - start_time
+ else:
+ if check_box_rembg or image.mode == "RGB":
+ start_time = time.time()
+ image = rmbg_worker(image.convert('RGB'))
+ time_meta['remove background'] = time.time() - start_time
+
+ # remove disk io to make responding faster, uncomment at your will.
+ # image.save(os.path.join(save_folder, 'rembg.png'))
+
+ # image to white model
+ start_time = time.time()
+
+ generator = torch.Generator()
+ generator = generator.manual_seed(int(seed))
+ outputs = i23d_worker(
+ image=image,
+ num_inference_steps=steps,
+ guidance_scale=guidance_scale,
+ generator=generator,
+ octree_resolution=octree_resolution,
+ num_chunks=num_chunks,
+ output_type='mesh'
+ )
+ time_meta['shape generation'] = time.time() - start_time
+ logger.info("---Shape generation takes %s seconds ---" % (time.time() - start_time))
+
+ tmp_start = time.time()
+ mesh = export_to_trimesh(outputs)[0]
+ time_meta['export to trimesh'] = time.time() - tmp_start
+
+ stats['number_of_faces'] = mesh.faces.shape[0]
+ stats['number_of_vertices'] = mesh.vertices.shape[0]
+
+ stats['time'] = time_meta
+ main_image = image if not MV_MODE else image['front']
+ return mesh, main_image, save_folder, stats, seed
+
+@spaces.GPU(duration=180)
+def generation_all(
+ caption=None,
+ image=None,
+ mv_image_front=None,
+ mv_image_back=None,
+ mv_image_left=None,
+ mv_image_right=None,
+ steps=50,
+ guidance_scale=7.5,
+ seed=1234,
+ octree_resolution=256,
+ check_box_rembg=False,
+ num_chunks=200000,
+ randomize_seed: bool = False,
+):
+ start_time_0 = time.time()
+ mesh, image, save_folder, stats, seed = _gen_shape(
+ caption,
+ image,
+ mv_image_front=mv_image_front,
+ mv_image_back=mv_image_back,
+ mv_image_left=mv_image_left,
+ mv_image_right=mv_image_right,
+ steps=steps,
+ guidance_scale=guidance_scale,
+ seed=seed,
+ octree_resolution=octree_resolution,
+ check_box_rembg=check_box_rembg,
+ num_chunks=num_chunks,
+ randomize_seed=randomize_seed,
+ )
+ path = export_mesh(mesh, save_folder, textured=False)
+
+
+ print(path)
+ print('='*40)
+
+ # tmp_time = time.time()
+ # mesh = floater_remove_worker(mesh)
+ # mesh = degenerate_face_remove_worker(mesh)
+ # logger.info("---Postprocessing takes %s seconds ---" % (time.time() - tmp_time))
+ # stats['time']['postprocessing'] = time.time() - tmp_time
+
+ tmp_time = time.time()
+ mesh = face_reduce_worker(mesh)
+
+ # path = export_mesh(mesh, save_folder, textured=False, type='glb')
+ path = export_mesh(mesh, save_folder, textured=False, type='obj') # 这样操作也会 core dump
+
+ logger.info("---Face Reduction takes %s seconds ---" % (time.time() - tmp_time))
+ stats['time']['face reduction'] = time.time() - tmp_time
+
+ tmp_time = time.time()
+
+ text_path = os.path.join(save_folder, f'textured_mesh.obj')
+ path_textured = tex_pipeline(mesh_path=path, image_path=image, output_mesh_path=text_path, save_glb=False)
+
+ logger.info("---Texture Generation takes %s seconds ---" % (time.time() - tmp_time))
+ stats['time']['texture generation'] = time.time() - tmp_time
+
+ tmp_time = time.time()
+ # Convert textured OBJ to GLB using obj2gltf with PBR support
+ glb_path_textured = os.path.join(save_folder, 'textured_mesh.glb')
+ conversion_success = quick_convert_with_obj2gltf(path_textured, glb_path_textured)
+
+ logger.info("---Convert textured OBJ to GLB takes %s seconds ---" % (time.time() - tmp_time))
+ stats['time']['convert textured OBJ to GLB'] = time.time() - tmp_time
+ stats['time']['total'] = time.time() - start_time_0
+ model_viewer_html_textured = build_model_viewer_html(save_folder,
+ height=HTML_HEIGHT,
+ width=HTML_WIDTH, textured=True)
+ if args.low_vram_mode:
+ torch.cuda.empty_cache()
+ return (
+ gr.update(value=path),
+ gr.update(value=glb_path_textured),
+ model_viewer_html_textured,
+ stats,
+ seed,
+ )
+
+@spaces.GPU(duration=60)
+def shape_generation(
+ caption=None,
+ image=None,
+ mv_image_front=None,
+ mv_image_back=None,
+ mv_image_left=None,
+ mv_image_right=None,
+ steps=50,
+ guidance_scale=7.5,
+ seed=1234,
+ octree_resolution=256,
+ check_box_rembg=False,
+ num_chunks=200000,
+ randomize_seed: bool = False,
+):
+ start_time_0 = time.time()
+ mesh, image, save_folder, stats, seed = _gen_shape(
+ caption,
+ image,
+ mv_image_front=mv_image_front,
+ mv_image_back=mv_image_back,
+ mv_image_left=mv_image_left,
+ mv_image_right=mv_image_right,
+ steps=steps,
+ guidance_scale=guidance_scale,
+ seed=seed,
+ octree_resolution=octree_resolution,
+ check_box_rembg=check_box_rembg,
+ num_chunks=num_chunks,
+ randomize_seed=randomize_seed,
+ )
+ stats['time']['total'] = time.time() - start_time_0
+ mesh.metadata['extras'] = stats
+
+ path = export_mesh(mesh, save_folder, textured=False)
+ model_viewer_html = build_model_viewer_html(save_folder, height=HTML_HEIGHT, width=HTML_WIDTH)
+ if args.low_vram_mode:
+ torch.cuda.empty_cache()
+ return (
+ gr.update(value=path),
+ model_viewer_html,
+ stats,
+ seed,
+ )
+
+
+def build_app():
+ title = 'Hunyuan3D-2: High Resolution Textured 3D Assets Generation'
+ if MV_MODE:
+ title = 'Hunyuan3D-2mv: Image to 3D Generation with 1-4 Views'
+ if 'mini' in args.subfolder:
+ title = 'Hunyuan3D-2mini: Strong 0.6B Image to Shape Generator'
+
+ title = 'Hunyuan-3D-2.1'
+
+ if TURBO_MODE:
+ title = title.replace(':', '-Turbo: Fast ')
+
+ title_html = f"""
+
+
+ {title}
+
+
+ Tencent Hunyuan3D Team
+
+ """
+ custom_css = """
+ .app.svelte-wpkpf6.svelte-wpkpf6:not(.fill_width) {
+ max-width: 1480px;
+ }
+ .mv-image button .wrap {
+ font-size: 10px;
+ }
+
+ .mv-image .icon-wrap {
+ width: 20px;
+ }
+
+ """
+
+ with gr.Blocks(theme=gr.themes.Base(), title='Hunyuan-3D-2.1', analytics_enabled=False, css=custom_css) as demo:
+ gr.HTML(title_html)
+
+ with gr.Row():
+ with gr.Column(scale=3):
+ with gr.Tabs(selected='tab_img_prompt') as tabs_prompt:
+ with gr.Tab('Image Prompt', id='tab_img_prompt', visible=not MV_MODE) as tab_ip:
+ image = gr.Image(label='Image', type='pil', image_mode='RGBA', height=290)
+ caption = gr.State(None)
+# with gr.Tab('Text Prompt', id='tab_txt_prompt', visible=HAS_T2I and not MV_MODE) as tab_tp:
+# caption = gr.Textbox(label='Text Prompt',
+# placeholder='HunyuanDiT will be used to generate image.',
+# info='Example: A 3D model of a cute cat, white background')
+ with gr.Tab('MultiView Prompt', visible=MV_MODE) as tab_mv:
+ # gr.Label('Please upload at least one front image.')
+ with gr.Row():
+ mv_image_front = gr.Image(label='Front', type='pil', image_mode='RGBA', height=140,
+ min_width=100, elem_classes='mv-image')
+ mv_image_back = gr.Image(label='Back', type='pil', image_mode='RGBA', height=140,
+ min_width=100, elem_classes='mv-image')
+ with gr.Row():
+ mv_image_left = gr.Image(label='Left', type='pil', image_mode='RGBA', height=140,
+ min_width=100, elem_classes='mv-image')
+ mv_image_right = gr.Image(label='Right', type='pil', image_mode='RGBA', height=140,
+ min_width=100, elem_classes='mv-image')
+
+ with gr.Row():
+ btn = gr.Button(value='Gen Shape', variant='primary', min_width=100)
+ btn_all = gr.Button(value='Gen Textured Shape',
+ variant='primary',
+ visible=HAS_TEXTUREGEN,
+ min_width=100)
+
+ with gr.Group():
+ file_out = gr.File(label="File", visible=False)
+ file_out2 = gr.File(label="File", visible=False)
+
+ with gr.Tabs(selected='tab_options' if TURBO_MODE else 'tab_export'):
+ with gr.Tab("Options", id='tab_options', visible=TURBO_MODE):
+ gen_mode = gr.Radio(
+ label='Generation Mode',
+ info='Recommendation: Turbo for most cases, \
+Fast for very complex cases, Standard seldom use.',
+ choices=['Turbo', 'Fast', 'Standard'],
+ value='Turbo')
+ decode_mode = gr.Radio(
+ label='Decoding Mode',
+ info='The resolution for exporting mesh from generated vectset',
+ choices=['Low', 'Standard', 'High'],
+ value='Standard')
+ with gr.Tab('Advanced Options', id='tab_advanced_options'):
+ with gr.Row():
+ check_box_rembg = gr.Checkbox(
+ value=True,
+ label='Remove Background',
+ min_width=100)
+ randomize_seed = gr.Checkbox(
+ label="Randomize seed",
+ value=True,
+ min_width=100)
+ seed = gr.Slider(
+ label="Seed",
+ minimum=0,
+ maximum=MAX_SEED,
+ step=1,
+ value=1234,
+ min_width=100,
+ )
+ with gr.Row():
+ num_steps = gr.Slider(maximum=100,
+ minimum=1,
+ value=5 if 'turbo' in args.subfolder else 30,
+ step=1, label='Inference Steps')
+ octree_resolution = gr.Slider(maximum=512,
+ minimum=16,
+ value=256,
+ label='Octree Resolution')
+ with gr.Row():
+ cfg_scale = gr.Number(value=5.0, label='Guidance Scale', min_width=100)
+ num_chunks = gr.Slider(maximum=5000000, minimum=1000, value=8000,
+ label='Number of Chunks', min_width=100)
+ with gr.Tab("Export", id='tab_export'):
+ with gr.Row():
+ file_type = gr.Dropdown(label='File Type',
+ choices=SUPPORTED_FORMATS,
+ value='glb', min_width=100)
+ reduce_face = gr.Checkbox(label='Simplify Mesh',
+ value=False, min_width=100)
+ export_texture = gr.Checkbox(label='Include Texture', value=False,
+ visible=False, min_width=100)
+ target_face_num = gr.Slider(maximum=1000000, minimum=100, value=10000,
+ label='Target Face Number')
+ with gr.Row():
+ confirm_export = gr.Button(value="Transform", min_width=100)
+ file_export = gr.DownloadButton(label="Download", variant='primary',
+ interactive=False, min_width=100)
+
+ with gr.Column(scale=6):
+ with gr.Tabs(selected='gen_mesh_panel') as tabs_output:
+ with gr.Tab('Generated Mesh', id='gen_mesh_panel'):
+ html_gen_mesh = gr.HTML(HTML_OUTPUT_PLACEHOLDER, label='Output')
+ with gr.Tab('Exporting Mesh', id='export_mesh_panel'):
+ html_export_mesh = gr.HTML(HTML_OUTPUT_PLACEHOLDER, label='Output')
+ with gr.Tab('Mesh Statistic', id='stats_panel'):
+ stats = gr.Json({}, label='Mesh Stats')
+
+ with gr.Column(scale=3 if MV_MODE else 2):
+ with gr.Tabs(selected='tab_img_gallery') as gallery:
+ with gr.Tab('Image to 3D Gallery',
+ id='tab_img_gallery',
+ visible=not MV_MODE) as tab_gi:
+ with gr.Row():
+ gr.Examples(examples=example_is, inputs=[image],
+ label=None, examples_per_page=18)
+
+ tab_ip.select(fn=lambda: gr.update(selected='tab_img_gallery'), outputs=gallery)
+ #if HAS_T2I:
+ # tab_tp.select(fn=lambda: gr.update(selected='tab_txt_gallery'), outputs=gallery)
+
+ btn.click(
+ shape_generation,
+ inputs=[
+ caption,
+ image,
+ mv_image_front,
+ mv_image_back,
+ mv_image_left,
+ mv_image_right,
+ num_steps,
+ cfg_scale,
+ seed,
+ octree_resolution,
+ check_box_rembg,
+ num_chunks,
+ randomize_seed,
+ ],
+ outputs=[file_out, html_gen_mesh, stats, seed]
+ ).then(
+ lambda: (gr.update(visible=False, value=False), gr.update(interactive=True), gr.update(interactive=True),
+ gr.update(interactive=False)),
+ outputs=[export_texture, reduce_face, confirm_export, file_export],
+ ).then(
+ lambda: gr.update(selected='gen_mesh_panel'),
+ outputs=[tabs_output],
+ )
+
+ btn_all.click(
+ generation_all,
+ inputs=[
+ caption,
+ image,
+ mv_image_front,
+ mv_image_back,
+ mv_image_left,
+ mv_image_right,
+ num_steps,
+ cfg_scale,
+ seed,
+ octree_resolution,
+ check_box_rembg,
+ num_chunks,
+ randomize_seed,
+ ],
+ outputs=[file_out, file_out2, html_gen_mesh, stats, seed]
+ ).then(
+ lambda: (gr.update(visible=True, value=True), gr.update(interactive=False), gr.update(interactive=True),
+ gr.update(interactive=False)),
+ outputs=[export_texture, reduce_face, confirm_export, file_export],
+ ).then(
+ lambda: gr.update(selected='gen_mesh_panel'),
+ outputs=[tabs_output],
+ )
+
+ def on_gen_mode_change(value):
+ if value == 'Turbo':
+ return gr.update(value=5)
+ elif value == 'Fast':
+ return gr.update(value=10)
+ else:
+ return gr.update(value=30)
+
+ gen_mode.change(on_gen_mode_change, inputs=[gen_mode], outputs=[num_steps])
+
+ def on_decode_mode_change(value):
+ if value == 'Low':
+ return gr.update(value=196)
+ elif value == 'Standard':
+ return gr.update(value=256)
+ else:
+ return gr.update(value=384)
+
+ decode_mode.change(on_decode_mode_change, inputs=[decode_mode],
+ outputs=[octree_resolution])
+
+ def on_export_click(file_out, file_out2, file_type,
+ reduce_face, export_texture, target_face_num):
+ if file_out is None:
+ raise gr.Error('Please generate a mesh first.')
+
+ print(f'exporting {file_out}')
+ print(f'reduce face to {target_face_num}')
+ if export_texture:
+ mesh = trimesh.load(file_out2)
+ save_folder = gen_save_folder()
+ path = export_mesh(mesh, save_folder, textured=True, type=file_type)
+
+ # for preview
+ save_folder = gen_save_folder()
+ _ = export_mesh(mesh, save_folder, textured=True)
+ model_viewer_html = build_model_viewer_html(save_folder,
+ height=HTML_HEIGHT,
+ width=HTML_WIDTH,
+ textured=True)
+ else:
+ mesh = trimesh.load(file_out)
+ mesh = floater_remove_worker(mesh)
+ mesh = degenerate_face_remove_worker(mesh)
+ if reduce_face:
+ mesh = face_reduce_worker(mesh, target_face_num)
+ save_folder = gen_save_folder()
+ path = export_mesh(mesh, save_folder, textured=False, type=file_type)
+
+ # for preview
+ save_folder = gen_save_folder()
+ _ = export_mesh(mesh, save_folder, textured=False)
+ model_viewer_html = build_model_viewer_html(save_folder,
+ height=HTML_HEIGHT,
+ width=HTML_WIDTH,
+ textured=False)
+ print(f'export to {path}')
+ return model_viewer_html, gr.update(value=path, interactive=True)
+
+ confirm_export.click(
+ lambda: gr.update(selected='export_mesh_panel'),
+ outputs=[tabs_output],
+ ).then(
+ on_export_click,
+ inputs=[file_out, file_out2, file_type, reduce_face, export_texture, target_face_num],
+ outputs=[html_export_mesh, file_export]
+ )
+
+ return demo
+
+
+if __name__ == '__main__':
+ import argparse
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--model_path", type=str, default='tencent/Hunyuan3D-2.1')
+ parser.add_argument("--subfolder", type=str, default='hunyuan3d-dit-v2-1')
+ parser.add_argument("--texgen_model_path", type=str, default='tencent/Hunyuan3D-2.1')
+ parser.add_argument('--port', type=int, default=7860)
+ parser.add_argument('--host', type=str, default='0.0.0.0')
+ parser.add_argument('--device', type=str, default='cuda')
+ parser.add_argument('--mc_algo', type=str, default='mc')
+ parser.add_argument('--cache-path', type=str, default='/root/save_dir')
+ parser.add_argument('--enable_t23d', action='store_true')
+ parser.add_argument('--disable_tex', action='store_true')
+ parser.add_argument('--enable_flashvdm', action='store_true')
+ parser.add_argument('--compile', action='store_true')
+ parser.add_argument('--low_vram_mode', action='store_true')
+ args = parser.parse_args()
+ args.enable_flashvdm = False
+
+ SAVE_DIR = args.cache_path
+ os.makedirs(SAVE_DIR, exist_ok=True)
+
+ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
+ MV_MODE = 'mv' in args.model_path
+ TURBO_MODE = 'turbo' in args.subfolder
+
+ HTML_HEIGHT = 690 if MV_MODE else 650
+ HTML_WIDTH = 500
+ HTML_OUTPUT_PLACEHOLDER = f"""
+
+
+
Welcome to Hunyuan3D!
+
No mesh here.
+
+
+ """
+
+ INPUT_MESH_HTML = """
+
+
+ """
+ example_is = get_example_img_list()
+ example_ts = get_example_txt_list()
+
+ SUPPORTED_FORMATS = ['glb', 'obj', 'ply', 'stl']
+
+ HAS_TEXTUREGEN = False
+ if not args.disable_tex:
+ try:
+ # Apply torchvision fix before importing basicsr/RealESRGAN
+ print("Applying torchvision compatibility fix for texture generation...")
+ try:
+ from torchvision_fix import apply_fix
+ fix_result = apply_fix()
+ if not fix_result:
+ print("Warning: Torchvision fix may not have been applied successfully")
+ except Exception as fix_error:
+ print(f"Warning: Failed to apply torchvision fix: {fix_error}")
+
+ # from hy3dgen.texgen import Hunyuan3DPaintPipeline
+ # texgen_worker = Hunyuan3DPaintPipeline.from_pretrained(args.texgen_model_path)
+ # if args.low_vram_mode:
+ # texgen_worker.enable_model_cpu_offload()
+
+ from hy3dpaint.textureGenPipeline import Hunyuan3DPaintPipeline, Hunyuan3DPaintConfig
+ conf = Hunyuan3DPaintConfig(max_num_view=8, resolution=768)
+ conf.realesrgan_ckpt_path = "hy3dpaint/ckpt/RealESRGAN_x4plus.pth"
+ conf.multiview_cfg_path = "hy3dpaint/cfgs/hunyuan-paint-pbr.yaml"
+ conf.custom_pipeline = "hy3dpaint/hunyuanpaintpbr"
+ tex_pipeline = Hunyuan3DPaintPipeline(conf)
+
+ # Not help much, ignore for now.
+ # if args.compile:
+ # texgen_worker.models['delight_model'].pipeline.unet.compile()
+ # texgen_worker.models['delight_model'].pipeline.vae.compile()
+ # texgen_worker.models['multiview_model'].pipeline.unet.compile()
+ # texgen_worker.models['multiview_model'].pipeline.vae.compile()
+
+ HAS_TEXTUREGEN = True
+
+ except Exception as e:
+ print(f"Error loading texture generator: {e}")
+ print("Failed to load texture generator.")
+ print('Please try to install requirements by following README.md')
+ HAS_TEXTUREGEN = False
+
+ # HAS_T2I = True
+ # if args.enable_t23d:
+ # from hy3dgen.text2image import HunyuanDiTPipeline
+
+ # t2i_worker = HunyuanDiTPipeline('Tencent-Hunyuan/HunyuanDiT-v1.1-Diffusers-Distilled')
+ # HAS_T2I = True
+
+ from hy3dshape import FaceReducer, FloaterRemover, DegenerateFaceRemover, MeshSimplifier, \
+ Hunyuan3DDiTFlowMatchingPipeline
+ from hy3dshape.pipelines import export_to_trimesh
+ from hy3dshape.rembg import BackgroundRemover
+
+ rmbg_worker = BackgroundRemover()
+ i23d_worker = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained(
+ args.model_path,
+ subfolder=args.subfolder,
+ use_safetensors=False,
+ device=args.device,
+ )
+ if args.enable_flashvdm:
+ mc_algo = 'mc' if args.device in ['cpu', 'mps'] else args.mc_algo
+ i23d_worker.enable_flashvdm(mc_algo=mc_algo)
+ if args.compile:
+ i23d_worker.compile()
+
+ floater_remove_worker = FloaterRemover()
+ degenerate_face_remove_worker = DegenerateFaceRemover()
+ face_reduce_worker = FaceReducer()
+
+ # https://discuss.huggingface.co/t/how-to-serve-an-html-file/33921/2
+ # create a FastAPI app
+ app = FastAPI()
+
+ # create a static directory to store the static files
+ static_dir = Path(SAVE_DIR).absolute()
+ static_dir.mkdir(parents=True, exist_ok=True)
+ app.mount("/static", StaticFiles(directory=static_dir, html=True), name="static")
+ shutil.copytree('./assets/env_maps', os.path.join(static_dir, 'env_maps'), dirs_exist_ok=True)
+
+ if args.low_vram_mode:
+ torch.cuda.empty_cache()
+
+ demo = build_app()
+ app = gr.mount_gradio_app(app, demo, path="/")
+
+ if ENV == 'Huggingface':
+ # for Zerogpu
+ from spaces import zero
+ zero.startup()
+
+ uvicorn.run(app, host=args.host, port=args.port)
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/MeshRender.py b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/MeshRender.py
new file mode 100644
index 0000000000000000000000000000000000000000..83c8cf8d9a74d29e2a96756673c9987f9c38fd02
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/MeshRender.py
@@ -0,0 +1,1414 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import cv2
+import torch
+import trimesh
+import numpy as np
+from PIL import Image
+import torch.nn.functional as F
+from typing import Union, Optional, Tuple, List, Any, Callable
+from dataclasses import dataclass
+from enum import Enum
+from .camera_utils import (
+ transform_pos,
+ get_mv_matrix,
+ get_orthographic_projection_matrix,
+ get_perspective_projection_matrix,
+)
+
+try:
+ from .mesh_utils import load_mesh, save_mesh
+except:
+ print("Bpy IO CAN NOT BE Imported!!!")
+
+try:
+ from .mesh_inpaint_processor import meshVerticeInpaint # , meshVerticeColor
+except:
+ print("InPaint Function CAN NOT BE Imported!!!")
+
+
+class RenderMode(Enum):
+ """Rendering mode enumeration."""
+ NORMAL = "normal"
+ POSITION = "position"
+ ALPHA = "alpha"
+ UV_POS = "uvpos"
+
+
+class ReturnType(Enum):
+ """Return type enumeration."""
+ TENSOR = "th"
+ NUMPY = "np"
+ PIL = "pl"
+
+
+class TextureType(Enum):
+ """Texture type enumeration."""
+ DIFFUSE = "diffuse"
+ METALLIC_ROUGHNESS = "mr"
+ NORMAL = "normal"
+
+
+@dataclass
+class RenderConfig:
+ """Unified rendering configuration."""
+ elev: float = 0
+ azim: float = 0
+ camera_distance: Optional[float] = None
+ center: Optional[List[float]] = None
+ resolution: Optional[Union[int, Tuple[int, int]]] = None
+ bg_color: List[float] = None
+ return_type: str = "th"
+
+ def __post_init__(self):
+ if self.bg_color is None:
+ self.bg_color = [1, 1, 1]
+
+
+@dataclass
+class ViewState:
+ """Camera view state for rendering pipeline."""
+ proj_mat: torch.Tensor
+ mv_mat: torch.Tensor
+ pos_camera: torch.Tensor
+ pos_clip: torch.Tensor
+ resolution: Tuple[int, int]
+
+
+def stride_from_shape(shape):
+ """
+ Calculate stride values from a given shape for multi-dimensional indexing.
+
+ Args:
+ shape: Tuple or list representing tensor dimensions
+
+ Returns:
+ List of stride values for each dimension
+ """
+ stride = [1]
+ for x in reversed(shape[1:]):
+ stride.append(stride[-1] * x)
+ return list(reversed(stride))
+
+
+def scatter_add_nd_with_count(input, count, indices, values, weights=None):
+ """
+ Perform scatter-add operation on N-dimensional tensors with counting.
+
+ Args:
+ input: Input tensor [..., C] with D dimensions + C channels
+ count: Count tensor [..., 1] with D dimensions
+ indices: Index tensor [N, D] of type long
+ values: Value tensor [N, C] to scatter
+ weights: Optional weight tensor [N, C], defaults to ones if None
+
+ Returns:
+ Tuple of (updated_input, updated_count) tensors
+ """
+ # input: [..., C], D dimension + C channel
+ # count: [..., 1], D dimension
+ # indices: [N, D], long
+ # values: [N, C]
+
+ D = indices.shape[-1]
+ C = input.shape[-1]
+ size = input.shape[:-1]
+ stride = stride_from_shape(size)
+
+ assert len(size) == D
+
+ input = input.view(-1, C) # [HW, C]
+ count = count.view(-1, 1)
+
+ flatten_indices = (indices * torch.tensor(stride, dtype=torch.long, device=indices.device)).sum(-1) # [N]
+
+ if weights is None:
+ weights = torch.ones_like(values[..., :1])
+
+ input.scatter_add_(0, flatten_indices.unsqueeze(1).repeat(1, C), values)
+ count.scatter_add_(0, flatten_indices.unsqueeze(1), weights)
+
+ return input.view(*size, C), count.view(*size, 1)
+
+
+def linear_grid_put_2d(H, W, coords, values, return_count=False):
+ """
+ Place values on a 2D grid using bilinear interpolation.
+
+ Args:
+ H: Grid height
+ W: Grid width
+ coords: Coordinate tensor [N, 2] with values in range [0, 1]
+ values: Value tensor [N, C] to place on grid
+ return_count: Whether to return count information
+
+ Returns:
+ 2D grid tensor [H, W, C] with interpolated values, optionally with count tensor
+ """
+ # coords: [N, 2], float in [0, 1]
+ # values: [N, C]
+
+ C = values.shape[-1]
+
+ indices = coords * torch.tensor([H - 1, W - 1], dtype=torch.float32, device=coords.device)
+ indices_00 = indices.floor().long() # [N, 2]
+ indices_00[:, 0].clamp_(0, H - 2)
+ indices_00[:, 1].clamp_(0, W - 2)
+ indices_01 = indices_00 + torch.tensor([0, 1], dtype=torch.long, device=indices.device)
+ indices_10 = indices_00 + torch.tensor([1, 0], dtype=torch.long, device=indices.device)
+ indices_11 = indices_00 + torch.tensor([1, 1], dtype=torch.long, device=indices.device)
+
+ h = indices[..., 0] - indices_00[..., 0].float()
+ w = indices[..., 1] - indices_00[..., 1].float()
+ w_00 = (1 - h) * (1 - w)
+ w_01 = (1 - h) * w
+ w_10 = h * (1 - w)
+ w_11 = h * w
+
+ result = torch.zeros(H, W, C, device=values.device, dtype=values.dtype) # [H, W, C]
+ count = torch.zeros(H, W, 1, device=values.device, dtype=values.dtype) # [H, W, 1]
+ weights = torch.ones_like(values[..., :1]) # [N, 1]
+
+ result, count = scatter_add_nd_with_count(
+ result, count, indices_00, values * w_00.unsqueeze(1), weights * w_00.unsqueeze(1)
+ )
+ result, count = scatter_add_nd_with_count(
+ result, count, indices_01, values * w_01.unsqueeze(1), weights * w_01.unsqueeze(1)
+ )
+ result, count = scatter_add_nd_with_count(
+ result, count, indices_10, values * w_10.unsqueeze(1), weights * w_10.unsqueeze(1)
+ )
+ result, count = scatter_add_nd_with_count(
+ result, count, indices_11, values * w_11.unsqueeze(1), weights * w_11.unsqueeze(1)
+ )
+
+ if return_count:
+ return result, count
+
+ mask = count.squeeze(-1) > 0
+ result[mask] = result[mask] / count[mask].repeat(1, C)
+
+ return result
+
+
+def mipmap_linear_grid_put_2d(H, W, coords, values, min_resolution=128, return_count=False):
+ """
+ Place values on 2D grid using mipmap-based multiresolution interpolation to fill holes.
+
+ Args:
+ H: Grid height
+ W: Grid width
+ coords: Coordinate tensor [N, 2] with values in range [0, 1]
+ values: Value tensor [N, C] to place on grid
+ min_resolution: Minimum resolution for mipmap levels
+ return_count: Whether to return count information
+
+ Returns:
+ 2D grid tensor [H, W, C] with filled values, optionally with count tensor
+ """
+ # coords: [N, 2], float in [0, 1]
+ # values: [N, C]
+
+ C = values.shape[-1]
+
+ result = torch.zeros(H, W, C, device=values.device, dtype=values.dtype) # [H, W, C]
+ count = torch.zeros(H, W, 1, device=values.device, dtype=values.dtype) # [H, W, 1]
+
+ cur_H, cur_W = H, W
+
+ while min(cur_H, cur_W) > min_resolution:
+
+ # try to fill the holes
+ mask = count.squeeze(-1) == 0
+ if not mask.any():
+ break
+
+ cur_result, cur_count = linear_grid_put_2d(cur_H, cur_W, coords, values, return_count=True)
+ result[mask] = (
+ result[mask]
+ + F.interpolate(
+ cur_result.permute(2, 0, 1).unsqueeze(0).contiguous(), (H, W), mode="bilinear", align_corners=False
+ )
+ .squeeze(0)
+ .permute(1, 2, 0)
+ .contiguous()[mask]
+ )
+ count[mask] = (
+ count[mask]
+ + F.interpolate(cur_count.view(1, 1, cur_H, cur_W), (H, W), mode="bilinear", align_corners=False).view(
+ H, W, 1
+ )[mask]
+ )
+ cur_H //= 2
+ cur_W //= 2
+
+ if return_count:
+ return result, count
+
+ mask = count.squeeze(-1) > 0
+ result[mask] = result[mask] / count[mask].repeat(1, C)
+
+ return result
+
+
+# ============ Core utility functions for reducing duplication ============
+
+def _normalize_image_input(image: Union[np.ndarray, torch.Tensor, Image.Image]) -> Union[np.ndarray, torch.Tensor]:
+ """Normalize image input to consistent format."""
+ if isinstance(image, Image.Image):
+ return np.array(image) / 255.0
+ elif isinstance(image, torch.Tensor):
+ return image.cpu().numpy() if image.is_cuda else image
+ return image
+
+
+def _convert_texture_format(tex: Union[np.ndarray, torch.Tensor, Image.Image],
+ texture_size: Tuple[int, int], device: str, force_set: bool = False) -> torch.Tensor:
+ """Unified texture format conversion logic."""
+ if not force_set:
+ if isinstance(tex, np.ndarray):
+ tex = Image.fromarray((tex * 255).astype(np.uint8))
+ elif isinstance(tex, torch.Tensor):
+ tex_np = tex.cpu().numpy()
+ tex = Image.fromarray((tex_np * 255).astype(np.uint8))
+
+ tex = tex.resize(texture_size).convert("RGB")
+ tex = np.array(tex) / 255.0
+ return torch.from_numpy(tex).to(device).float()
+ else:
+ if isinstance(tex, np.ndarray):
+ tex = torch.from_numpy(tex)
+ return tex.to(device).float()
+
+
+def _format_output(image: torch.Tensor, return_type: str) -> Union[torch.Tensor, np.ndarray, Image.Image]:
+ """Convert output to requested format."""
+ if return_type == ReturnType.NUMPY.value:
+ return image.cpu().numpy()
+ elif return_type == ReturnType.PIL.value:
+ img_np = image.cpu().numpy() * 255
+ return Image.fromarray(img_np.astype(np.uint8))
+ return image
+
+
+def _ensure_resolution_format(resolution: Optional[Union[int, Tuple[int, int]]],
+ default: Tuple[int, int]) -> Tuple[int, int]:
+ """Ensure resolution is in (height, width) format."""
+ if resolution is None:
+ return default
+ if isinstance(resolution, (int, float)):
+ return (int(resolution), int(resolution))
+ return tuple(resolution)
+
+
+def _apply_background_mask(content: torch.Tensor, visible_mask: torch.Tensor,
+ bg_color: List[float], device: str) -> torch.Tensor:
+ """Apply background color to masked regions."""
+ bg_tensor = torch.tensor(bg_color, dtype=torch.float32, device=device)
+ return content * visible_mask + bg_tensor * (1 - visible_mask)
+
+
+class MeshRender:
+ def __init__(
+ self,
+ camera_distance=1.45,
+ camera_type="orth",
+ default_resolution=1024,
+ texture_size=1024,
+ use_antialias=True,
+ max_mip_level=None,
+ filter_mode="linear-mipmap-linear",
+ bake_mode="back_sample",
+ raster_mode="cr",
+ shader_type="face",
+ use_opengl=False,
+ device="cuda",
+ ):
+ """
+ Initialize mesh renderer with configurable parameters.
+
+ Args:
+ camera_distance: Distance from camera to object center
+ camera_type: Type of camera projection ("orth" or "perspective")
+ default_resolution: Default rendering resolution
+ texture_size: Size of texture maps
+ use_antialias: Whether to use antialiasing
+ max_mip_level: Maximum mipmap level for texture filtering
+ filter_mode: Texture filtering mode
+ bake_mode: Texture baking method ("back_sample", "linear", "mip-map")
+ raster_mode: Rasterization backend ("cr" for custom rasterizer)
+ shader_type: Shading type ("face" or "vertex")
+ use_opengl: Whether to use OpenGL backend (deprecated)
+ device: Computing device ("cuda" or "cpu")
+ """
+
+ self.device = device
+
+ self.set_default_render_resolution(default_resolution)
+ self.set_default_texture_resolution(texture_size)
+
+ self.camera_distance = camera_distance
+ self.use_antialias = use_antialias
+ self.max_mip_level = max_mip_level
+ self.filter_mode = filter_mode
+ self.bake_angle_thres = 75
+ self.set_boundary_unreliable_scale(2)
+ self.bake_mode = bake_mode
+ self.shader_type = shader_type
+
+ self.raster_mode = raster_mode
+ if self.raster_mode == "cr":
+ import custom_rasterizer as cr
+
+ self.raster = cr
+ else:
+ raise f"No raster named {self.raster_mode}"
+
+ if camera_type == "orth":
+ self.set_orth_scale(1.2)
+ elif camera_type == "perspective":
+ self.camera_proj_mat = get_perspective_projection_matrix(
+ 49.13, self.default_resolution[1] / self.default_resolution[0], 0.01, 100.0
+ )
+ else:
+ raise f"No camera type {camera_type}"
+
+ # Removed multiprocessing components for single-threaded version
+
+ def _create_view_state(self, config: RenderConfig) -> ViewState:
+ """Create unified view state for rendering pipeline."""
+ proj = self.camera_proj_mat
+ r_mv = get_mv_matrix(
+ elev=config.elev,
+ azim=config.azim,
+ camera_distance=self.camera_distance if config.camera_distance is None else config.camera_distance,
+ center=config.center,
+ )
+
+ pos_camera = transform_pos(r_mv, self.vtx_pos, keepdim=True)
+ pos_clip = transform_pos(proj, pos_camera)
+ resolution = _ensure_resolution_format(config.resolution, self.default_resolution)
+
+ return ViewState(proj, r_mv, pos_camera, pos_clip, resolution)
+
+ def _compute_face_normals(self, triangles: torch.Tensor) -> torch.Tensor:
+ """Compute face normals from triangle vertices."""
+ return F.normalize(
+ torch.cross(
+ triangles[:, 1, :] - triangles[:, 0, :],
+ triangles[:, 2, :] - triangles[:, 0, :],
+ dim=-1,
+ ),
+ dim=-1,
+ )
+
+ def _get_normals_for_shading(self, view_state: ViewState, use_abs_coor: bool = False) -> torch.Tensor:
+ """Get normals based on shader type and coordinate system."""
+ if use_abs_coor:
+ mesh_triangles = self.vtx_pos[self.pos_idx[:, :3], :]
+ else:
+ pos_camera = view_state.pos_camera[:, :3] / view_state.pos_camera[:, 3:4]
+ mesh_triangles = pos_camera[self.pos_idx[:, :3], :]
+
+ face_normals = self._compute_face_normals(mesh_triangles)
+
+ # Common rasterization
+ rast_out, _ = self.raster_rasterize(view_state.pos_clip, self.pos_idx, resolution=view_state.resolution)
+
+ if self.shader_type == "vertex":
+ vertex_normals = trimesh.geometry.mean_vertex_normals(
+ vertex_count=self.vtx_pos.shape[0],
+ faces=self.pos_idx.cpu(),
+ face_normals=face_normals.cpu(),
+ )
+ vertex_normals = torch.from_numpy(vertex_normals).float().to(self.device).contiguous()
+ normal, _ = self.raster_interpolate(vertex_normals[None, ...], rast_out, self.pos_idx)
+
+ elif self.shader_type == "face":
+ tri_ids = rast_out[..., 3]
+ tri_ids_mask = tri_ids > 0
+ tri_ids = ((tri_ids - 1) * tri_ids_mask).long()
+ normal = torch.zeros(rast_out.shape[0], rast_out.shape[1], rast_out.shape[2], 3).to(rast_out)
+ normal.reshape(-1, 3)[tri_ids_mask.view(-1)] = face_normals.reshape(-1, 3)[tri_ids[tri_ids_mask].view(-1)]
+
+ return normal, rast_out
+
+ def _unified_render_pipeline(self, config: RenderConfig, mode: RenderMode, **kwargs) -> torch.Tensor:
+ """Unified rendering pipeline for all render modes."""
+ view_state = self._create_view_state(config)
+
+ if mode == RenderMode.ALPHA:
+ rast_out, _ = self.raster_rasterize(view_state.pos_clip, self.pos_idx, resolution=view_state.resolution)
+ return rast_out[..., -1:].long()
+
+ elif mode == RenderMode.UV_POS:
+ return self.uv_feature_map(self.vtx_pos * 0.5 + 0.5)
+
+ elif mode == RenderMode.NORMAL:
+ use_abs_coor = kwargs.get('use_abs_coor', False)
+ normalize_rgb = kwargs.get('normalize_rgb', True)
+
+ normal, rast_out = self._get_normals_for_shading(view_state, use_abs_coor)
+ visible_mask = torch.clamp(rast_out[..., -1:], 0, 1)
+
+ result = _apply_background_mask(normal, visible_mask, config.bg_color, self.device)
+
+ if normalize_rgb:
+ result = (result + 1) * 0.5
+
+ if self.use_antialias:
+ result = self.raster_antialias(result, rast_out, view_state.pos_clip, self.pos_idx)
+
+ return result[0, ...]
+
+ elif mode == RenderMode.POSITION:
+ rast_out, _ = self.raster_rasterize(view_state.pos_clip, self.pos_idx, resolution=view_state.resolution)
+
+ tex_position = 0.5 - self.vtx_pos[:, :3] / self.scale_factor
+ tex_position = tex_position.contiguous()
+
+ position, _ = self.raster_interpolate(tex_position[None, ...], rast_out, self.pos_idx)
+ visible_mask = torch.clamp(rast_out[..., -1:], 0, 1)
+
+ result = _apply_background_mask(position, visible_mask, config.bg_color, self.device)
+
+ if self.use_antialias:
+ result = self.raster_antialias(result, rast_out, view_state.pos_clip, self.pos_idx)
+
+ return result[0, ...]
+
+ def set_orth_scale(self, ortho_scale):
+ """
+ Set the orthographic projection scale and update camera projection matrix.
+
+ Args:
+ ortho_scale: Scale factor for orthographic projection
+ """
+ self.ortho_scale = ortho_scale
+ self.camera_proj_mat = get_orthographic_projection_matrix(
+ left=-self.ortho_scale * 0.5,
+ right=self.ortho_scale * 0.5,
+ bottom=-self.ortho_scale * 0.5,
+ top=self.ortho_scale * 0.5,
+ near=0.1,
+ far=100,
+ )
+
+ def raster_rasterize(self, pos, tri, resolution, ranges=None, grad_db=True):
+ """
+ Rasterize triangular mesh using the configured rasterization backend.
+
+ Args:
+ pos: Vertex positions in clip space
+ tri: Triangle indices
+ resolution: Rendering resolution [height, width]
+ ranges: Optional rendering ranges (unused in current implementation)
+ grad_db: Whether to compute gradients (unused in current implementation)
+
+ Returns:
+ Tuple of (rasterization_output, gradient_info)
+ """
+
+ if self.raster_mode == "cr":
+ rast_out_db = None
+ if pos.dim() == 2:
+ pos = pos.unsqueeze(0)
+
+ # 确保pos是float32类型
+ if pos.dtype == torch.float64:
+ pos = pos.to(torch.float32)
+
+ # 确保tri是int32类型
+ if tri.dtype == torch.int64:
+ tri = tri.to(torch.int32)
+
+ findices, barycentric = self.raster.rasterize(pos, tri, resolution)
+ rast_out = torch.cat((barycentric, findices.unsqueeze(-1)), dim=-1)
+ rast_out = rast_out.unsqueeze(0)
+ else:
+ raise f"No raster named {self.raster_mode}"
+
+ return rast_out, rast_out_db
+
+ def raster_interpolate(self, uv, rast_out, uv_idx):
+ """
+ Interpolate texture coordinates or vertex attributes across rasterized triangles.
+
+ Args:
+ uv: UV coordinates or vertex attributes to interpolate
+ rast_out: Rasterization output containing barycentric coordinates
+ uv_idx: UV or vertex indices for triangles
+
+ Returns:
+ Tuple of (interpolated_values, gradient_info)
+ """
+
+ if self.raster_mode == "cr":
+ textd = None
+ barycentric = rast_out[0, ..., :-1]
+ findices = rast_out[0, ..., -1]
+ if uv.dim() == 2:
+ uv = uv.unsqueeze(0)
+ textc = self.raster.interpolate(uv, findices, barycentric, uv_idx)
+ else:
+ raise f"No raster named {self.raster_mode}"
+
+ return textc, textd
+
+ def raster_antialias(self, color, rast, pos, tri, topology_hash=None, pos_gradient_boost=1.0):
+ """
+ Apply antialiasing to rendered colors (currently returns input unchanged).
+
+ Args:
+ color: Input color values
+ rast: Rasterization output
+ pos: Vertex positions
+ tri: Triangle indices
+ topology_hash: Optional topology hash for optimization
+ pos_gradient_boost: Gradient boosting factor
+
+ Returns:
+ Antialiased color values
+ """
+
+ if self.raster_mode == "cr":
+ color = color
+ else:
+ raise f"No raster named {self.raster_mode}"
+
+ return color
+
+ def set_boundary_unreliable_scale(self, scale):
+ """
+ Set the kernel size for boundary unreliable region detection during texture baking.
+
+ Args:
+ scale: Scale factor relative to 512 resolution baseline
+ """
+ self.bake_unreliable_kernel_size = int(
+ (scale / 512) * max(self.default_resolution[0], self.default_resolution[1])
+ )
+
+ def load_mesh(
+ self,
+ mesh,
+ scale_factor=1.15,
+ auto_center=True,
+ ):
+ """
+ Load mesh from file and set up rendering data structures.
+
+ Args:
+ mesh: Path to mesh file or mesh object
+ scale_factor: Scaling factor for mesh normalization
+ auto_center: Whether to automatically center the mesh
+ """
+ vtx_pos, pos_idx, vtx_uv, uv_idx, texture_data = load_mesh(mesh)
+ self.set_mesh(
+ vtx_pos, pos_idx, vtx_uv=vtx_uv, uv_idx=uv_idx, scale_factor=scale_factor, auto_center=auto_center
+ )
+ if texture_data is not None:
+ self.set_texture(texture_data)
+
+ def save_mesh(self, mesh_path, downsample=False):
+ """
+ Save current mesh with textures to file.
+
+ Args:
+ mesh_path: Output file path
+ downsample: Whether to downsample textures by half
+ """
+
+ vtx_pos, pos_idx, vtx_uv, uv_idx = self.get_mesh(normalize=False)
+ texture_data = self.get_texture()
+ texture_metallic, texture_roughness = self.get_texture_mr()
+ texture_normal = self.get_texture_normal()
+ if downsample:
+ texture_data = cv2.resize(texture_data, (texture_data.shape[1] // 2, texture_data.shape[0] // 2))
+ if texture_metallic is not None:
+ texture_metallic = cv2.resize(
+ texture_metallic, (texture_metallic.shape[1] // 2, texture_metallic.shape[0] // 2)
+ )
+ if texture_roughness is not None:
+ texture_roughness = cv2.resize(
+ texture_roughness, (texture_roughness.shape[1] // 2, texture_roughness.shape[0] // 2)
+ )
+ if texture_normal is not None:
+ texture_normal = cv2.resize(
+ texture_normal, (texture_normal.shape[1] // 2, texture_normal.shape[0] // 2)
+ )
+
+ save_mesh(
+ mesh_path,
+ vtx_pos,
+ pos_idx,
+ vtx_uv,
+ uv_idx,
+ texture_data,
+ metallic=texture_metallic,
+ roughness=texture_roughness,
+ normal=texture_normal,
+ )
+
+ def set_mesh(self, vtx_pos, pos_idx, vtx_uv=None, uv_idx=None, scale_factor=1.15, auto_center=True):
+ """
+ Set mesh geometry data and perform coordinate transformations.
+
+ Args:
+ vtx_pos: Vertex positions [N, 3]
+ pos_idx: Triangle vertex indices [F, 3]
+ vtx_uv: UV coordinates [N, 2], optional
+ uv_idx: Triangle UV indices [F, 3], optional
+ scale_factor: Scaling factor for mesh normalization
+ auto_center: Whether to automatically center and scale the mesh
+ """
+ self.vtx_pos = torch.from_numpy(vtx_pos).to(self.device)
+ self.pos_idx = torch.from_numpy(pos_idx).to(self.device)
+
+ # 确保顶点位置是float32类型
+ if self.vtx_pos.dtype == torch.float64:
+ self.vtx_pos = self.vtx_pos.to(torch.float32)
+
+ # 确保索引类型为int32
+ if self.pos_idx.dtype == torch.int64:
+ self.pos_idx = self.pos_idx.to(torch.int32)
+
+ if (vtx_uv is not None) and (uv_idx is not None):
+ self.vtx_uv = torch.from_numpy(vtx_uv).to(self.device)
+ self.uv_idx = torch.from_numpy(uv_idx).to(self.device)
+
+ # 确保UV坐标是float32类型
+ if self.vtx_uv.dtype == torch.float64:
+ self.vtx_uv = self.vtx_uv.to(torch.float32)
+
+ # 确保UV索引类型为int32
+ if self.uv_idx.dtype == torch.int64:
+ self.uv_idx = self.uv_idx.to(torch.int32)
+ else:
+ self.vtx_uv = None
+ self.uv_idx = None
+
+ self.vtx_pos[:, [0, 1]] = -self.vtx_pos[:, [0, 1]]
+ self.vtx_pos[:, [1, 2]] = self.vtx_pos[:, [2, 1]]
+ if (vtx_uv is not None) and (uv_idx is not None):
+ self.vtx_uv[:, 1] = 1.0 - self.vtx_uv[:, 1]
+ pass
+
+ if auto_center:
+ max_bb = (self.vtx_pos - 0).max(0)[0]
+ min_bb = (self.vtx_pos - 0).min(0)[0]
+ center = (max_bb + min_bb) / 2
+ scale = torch.norm(self.vtx_pos - center, dim=1).max() * 2.0
+ self.vtx_pos = (self.vtx_pos - center) * (scale_factor / float(scale))
+ self.scale_factor = scale_factor
+ self.mesh_normalize_scale_factor = scale_factor / float(scale)
+ self.mesh_normalize_scale_center = center.unsqueeze(0).cpu().numpy()
+ else:
+ self.scale_factor = 1.0
+ self.mesh_normalize_scale_factor = 1.0
+ self.mesh_normalize_scale_center = np.array([[0, 0, 0]])
+
+ if uv_idx is not None:
+ self.extract_textiles()
+
+ def _set_texture_unified(self, tex: Union[np.ndarray, torch.Tensor, Image.Image],
+ texture_type: TextureType, force_set: bool = False):
+ """Unified texture setting method."""
+ converted_tex = _convert_texture_format(tex, self.texture_size, self.device, force_set)
+
+ if texture_type == TextureType.DIFFUSE:
+ self.tex = converted_tex
+ elif texture_type == TextureType.METALLIC_ROUGHNESS:
+ self.tex_mr = converted_tex
+ elif texture_type == TextureType.NORMAL:
+ self.tex_normalMap = converted_tex
+
+ def set_texture(self, tex, force_set=False):
+ """Set the main diffuse texture for the mesh."""
+ self._set_texture_unified(tex, TextureType.DIFFUSE, force_set)
+
+ def set_texture_mr(self, mr, force_set=False):
+ """Set metallic-roughness texture for PBR rendering."""
+ self._set_texture_unified(mr, TextureType.METALLIC_ROUGHNESS, force_set)
+
+ def set_texture_normal(self, normal, force_set=False):
+ """Set normal map texture for surface detail."""
+ self._set_texture_unified(normal, TextureType.NORMAL, force_set)
+
+ def set_default_render_resolution(self, default_resolution):
+ """
+ Set the default resolution for rendering operations.
+
+ Args:
+ default_resolution: Resolution as int (square) or tuple (height, width)
+ """
+ if isinstance(default_resolution, int):
+ default_resolution = (default_resolution, default_resolution)
+ self.default_resolution = default_resolution
+
+ def set_default_texture_resolution(self, texture_size):
+ """
+ Set the default texture resolution for UV mapping operations.
+
+ Args:
+ texture_size: Texture size as int (square) or tuple (height, width)
+ """
+ if isinstance(texture_size, int):
+ texture_size = (texture_size, texture_size)
+ self.texture_size = texture_size
+
+ def get_face_num(self):
+ """
+ Get the number of triangular faces in the mesh.
+
+ Returns:
+ Number of faces as integer
+ """
+ return self.pos_idx.shape[0]
+
+ def get_vertex_num(self):
+ """
+ Get the number of vertices in the mesh.
+
+ Returns:
+ Number of vertices as integer
+ """
+ return self.vtx_pos.shape[0]
+
+ def get_face_areas(self, from_one_index=False):
+ """
+ Calculate the area of each triangular face in the mesh.
+
+ Args:
+ from_one_index: If True, insert zero at beginning for 1-indexed face IDs
+
+ Returns:
+ Numpy array of face areas
+ """
+ v0 = self.vtx_pos[self.pos_idx[:, 0], :]
+ v1 = self.vtx_pos[self.pos_idx[:, 1], :]
+ v2 = self.vtx_pos[self.pos_idx[:, 2], :]
+
+ # 计算两个边向量
+ edge1 = v1 - v0
+ edge2 = v2 - v0
+
+ # 计算叉积的模长的一半即为面积
+ areas = torch.norm(torch.cross(edge1, edge2, dim=-1), dim=-1) * 0.5
+
+ areas = areas.cpu().numpy()
+
+ if from_one_index:
+ # 在数组前面插入一个0,因为三角片索引是从1开始的
+ areas = np.insert(areas, 0, 0)
+
+ return areas
+
+ def get_mesh(self, normalize=True):
+ """
+ Get mesh geometry with optional coordinate denormalization.
+
+ Args:
+ normalize: Whether to keep normalized coordinates (True) or restore original scale (False)
+
+ Returns:
+ Tuple of (vertex_positions, face_indices, uv_coordinates, uv_indices)
+ """
+ vtx_pos = self.vtx_pos.cpu().numpy()
+ pos_idx = self.pos_idx.cpu().numpy()
+ vtx_uv = self.vtx_uv.cpu().numpy()
+ uv_idx = self.uv_idx.cpu().numpy()
+
+ # 坐标变换的逆变换
+ if not normalize:
+ vtx_pos = vtx_pos / self.mesh_normalize_scale_factor
+ vtx_pos = vtx_pos + self.mesh_normalize_scale_center
+ vtx_pos[:, [1, 2]] = vtx_pos[:, [2, 1]]
+ vtx_pos[:, [0, 1]] = -vtx_pos[:, [0, 1]]
+
+ vtx_uv[:, 1] = 1.0 - vtx_uv[:, 1]
+ return vtx_pos, pos_idx, vtx_uv, uv_idx
+
+ def get_texture(self):
+ """
+ Get the current diffuse texture as numpy array.
+
+ Returns:
+ Texture as numpy array in range [0, 1]
+ """
+ return self.tex.cpu().numpy()
+
+ def get_texture_mr(self):
+ """
+ Get metallic and roughness textures as separate channels.
+
+ Returns:
+ Tuple of (metallic_texture, roughness_texture) as numpy arrays, or (None, None) if not set
+ """
+ metallic, roughness = None, None
+ if hasattr(self, "tex_mr"):
+ mr = self.tex_mr.cpu().numpy()
+ metallic = np.repeat(mr[:, :, 0:1], repeats=3, axis=2)
+ roughness = np.repeat(mr[:, :, 1:2], repeats=3, axis=2)
+ return metallic, roughness
+
+ def get_texture_normal(self):
+ """
+ Get the normal map texture as numpy array.
+
+ Returns:
+ Normal map as numpy array, or None if not set
+ """
+ normal = None
+ if hasattr(self, "tex_normalMap"):
+ normal = self.tex_normalMap.cpu().numpy()
+ return normal
+
+ def to(self, device):
+ """
+ Move all tensor attributes to the specified device.
+
+ Args:
+ device: Target device ("cuda", "cpu", etc.)
+ """
+ self.device = device
+
+ for attr_name in dir(self):
+ attr_value = getattr(self, attr_name)
+ if isinstance(attr_value, torch.Tensor):
+ setattr(self, attr_name, attr_value.to(self.device))
+
+ def color_rgb_to_srgb(self, image):
+ """
+ Convert RGB color values to sRGB color space using gamma correction.
+
+ Args:
+ image: Input image as PIL Image, numpy array, or torch tensor
+
+ Returns:
+ sRGB corrected image in same format as input
+ """
+ if isinstance(image, Image.Image):
+ image_rgb = torch.tesnor(np.array(image) / 255.0).float().to(self.device)
+ elif isinstance(image, np.ndarray):
+ image_rgb = torch.tensor(image).float()
+ else:
+ image_rgb = image.to(self.device)
+
+ image_srgb = torch.where(
+ image_rgb <= 0.0031308, 12.92 * image_rgb, 1.055 * torch.pow(image_rgb, 1 / 2.4) - 0.055
+ )
+
+ if isinstance(image, Image.Image):
+ image_srgb = Image.fromarray((image_srgb.cpu().numpy() * 255).astype(np.uint8))
+ elif isinstance(image, np.ndarray):
+ image_srgb = image_srgb.cpu().numpy()
+ else:
+ image_srgb = image_srgb.to(image.device)
+
+ return image_srgb
+
+ def extract_textiles(self):
+ """
+ Extract texture-space position and normal information by rasterizing
+ the mesh in UV coordinate space. Creates texture-space geometry mappings.
+ """
+
+ vnum = self.vtx_uv.shape[0]
+ vtx_uv = torch.cat(
+ (self.vtx_uv, torch.zeros_like(self.vtx_uv[:, 0:1]), torch.ones_like(self.vtx_uv[:, 0:1])), axis=1
+ )
+ vtx_uv = vtx_uv.view(1, vnum, 4) * 2 - 1
+
+ rast_out, rast_out_db = self.raster_rasterize(vtx_uv, self.uv_idx, resolution=self.texture_size)
+ position, _ = self.raster_interpolate(self.vtx_pos, rast_out, self.pos_idx)
+
+ v0 = self.vtx_pos[self.pos_idx[:, 0], :]
+ v1 = self.vtx_pos[self.pos_idx[:, 1], :]
+ v2 = self.vtx_pos[self.pos_idx[:, 2], :]
+ face_normals = F.normalize(torch.cross(v1 - v0, v2 - v0, dim=-1), dim=-1)
+ vertex_normals = trimesh.geometry.mean_vertex_normals(
+ vertex_count=self.vtx_pos.shape[0],
+ faces=self.pos_idx.cpu(),
+ face_normals=face_normals.cpu(),
+ )
+ vertex_normals = torch.from_numpy(vertex_normals).to(self.vtx_pos).contiguous()
+ position_normal, _ = self.raster_interpolate(vertex_normals[None, ...], rast_out, self.pos_idx)
+ visible_mask = torch.clamp(rast_out[..., -1:], 0, 1)[0, ..., 0]
+ position = position[0]
+ position_normal = position_normal[0]
+ tri_ids = rast_out[0, ..., 3]
+ tri_ids_mask = tri_ids > 0
+ tri_ids = ((tri_ids - 1) * tri_ids_mask).long()
+ position_normal.reshape(-1, 3)[tri_ids_mask.view(-1)] = face_normals.reshape(-1, 3)[
+ tri_ids[tri_ids_mask].view(-1)
+ ]
+
+ row = torch.arange(position.shape[0]).to(visible_mask.device)
+ col = torch.arange(position.shape[1]).to(visible_mask.device)
+ grid_i, grid_j = torch.meshgrid(row, col, indexing="ij")
+
+ mask = visible_mask.reshape(-1) > 0
+ position = position.reshape(-1, 3)[mask]
+ position_normal = position_normal.reshape(-1, 3)[mask]
+ position = torch.cat((position, torch.ones_like(position[:, :1])), axis=-1)
+ grid = torch.stack((grid_i, grid_j), -1).reshape(-1, 2)[mask]
+
+ texture_indices = (
+ torch.ones(self.texture_size[0], self.texture_size[1], device=self.device, dtype=torch.long) * -1
+ )
+ texture_indices.view(-1)[grid[:, 0] * self.texture_size[1] + grid[:, 1]] = torch.arange(grid.shape[0]).to(
+ device=self.device, dtype=torch.long
+ )
+
+ self.tex_position = position
+ self.tex_normal = position_normal
+ self.tex_grid = grid
+ self.texture_indices = texture_indices
+
+ def render_normal(self, elev, azim, camera_distance=None, center=None, resolution=None,
+ bg_color=[1, 1, 1], use_abs_coor=False, normalize_rgb=True, return_type="th"):
+ """Render surface normals of the mesh from specified viewpoint."""
+ config = RenderConfig(elev, azim, camera_distance, center, resolution, bg_color, return_type)
+ image = self._unified_render_pipeline(config, RenderMode.NORMAL,
+ use_abs_coor=use_abs_coor, normalize_rgb=normalize_rgb)
+ return _format_output(image, return_type)
+
+ def convert_normal_map(self, image):
+ """
+ Convert normal map from standard format to renderer's coordinate system.
+ Applies coordinate transformations for proper normal interpretation.
+
+ Args:
+ image: Input normal map as PIL Image or numpy array
+
+ Returns:
+ Converted normal map as PIL Image
+ """
+ # blue is front, red is left, green is top
+ if isinstance(image, Image.Image):
+ image = np.array(image)
+ mask = (image == [255, 255, 255]).all(axis=-1)
+
+ image = (image / 255.0) * 2.0 - 1.0
+
+ image[..., [1]] = -image[..., [1]]
+ image[..., [1, 2]] = image[..., [2, 1]]
+ image[..., [0]] = -image[..., [0]]
+
+ image = (image + 1.0) * 0.5
+
+ image = (image * 255).astype(np.uint8)
+ image[mask] = [127, 127, 255]
+
+ return Image.fromarray(image)
+
+ def render_position(self, elev, azim, camera_distance=None, center=None, resolution=None,
+ bg_color=[1, 1, 1], return_type="th"):
+ """Render world-space positions of visible mesh surface points."""
+ config = RenderConfig(elev, azim, camera_distance, center, resolution, bg_color, return_type)
+ image = self._unified_render_pipeline(config, RenderMode.POSITION)
+
+ if return_type == ReturnType.PIL.value:
+ image = image.squeeze(-1).cpu().numpy() * 255
+ return Image.fromarray(image.astype(np.uint8))
+ return _format_output(image, return_type)
+
+ def render_uvpos(self, return_type="th"):
+ """Render vertex positions mapped to UV texture space."""
+ config = RenderConfig(return_type=return_type)
+ image = self._unified_render_pipeline(config, RenderMode.UV_POS)
+ return _format_output(image, return_type)
+
+ def render_alpha(self, elev, azim, camera_distance=None, center=None, resolution=None, return_type="th"):
+ """Render binary alpha mask indicating visible mesh regions."""
+ config = RenderConfig(elev, azim, camera_distance, center, resolution, return_type=return_type)
+ image = self._unified_render_pipeline(config, RenderMode.ALPHA)
+
+ if return_type == ReturnType.PIL.value:
+ raise Exception("PIL format not supported for alpha rendering")
+ return _format_output(image, return_type)
+
+ def uv_feature_map(self, vert_feat, bg=None):
+ """
+ Map per-vertex features to UV texture space using mesh topology.
+
+ Args:
+ vert_feat: Per-vertex feature tensor [N, C]
+ bg: Background value for unmapped regions (optional)
+
+ Returns:
+ Feature map in UV texture space [H, W, C]
+ """
+ vtx_uv = self.vtx_uv * 2 - 1.0
+ vtx_uv = torch.cat([vtx_uv, torch.zeros_like(self.vtx_uv)], dim=1).unsqueeze(0)
+ vtx_uv[..., -1] = 1
+ uv_idx = self.uv_idx
+ rast_out, rast_out_db = self.raster_rasterize(vtx_uv, uv_idx, resolution=self.texture_size)
+ feat_map, _ = self.raster_interpolate(vert_feat[None, ...], rast_out, uv_idx)
+ feat_map = feat_map[0, ...]
+ if bg is not None:
+ visible_mask = torch.clamp(rast_out[..., -1:], 0, 1)[0, ...]
+ feat_map[visible_mask == 0] = bg
+ return feat_map
+
+ def render_sketch_from_geometry(self, normal_image, depth_image):
+ """
+ Generate sketch-style edge image from rendered normal and depth maps.
+
+ Args:
+ normal_image: Rendered normal map tensor
+ depth_image: Rendered depth map tensor
+
+ Returns:
+ Binary edge sketch image as tensor
+ """
+ normal_image_np = normal_image.cpu().numpy()
+ depth_image_np = depth_image.cpu().numpy()
+
+ normal_image_np = (normal_image_np * 255).astype(np.uint8)
+ depth_image_np = (depth_image_np * 255).astype(np.uint8)
+ normal_image_np = cv2.cvtColor(normal_image_np, cv2.COLOR_RGB2GRAY)
+
+ normal_edges = cv2.Canny(normal_image_np, 80, 150)
+ depth_edges = cv2.Canny(depth_image_np, 30, 80)
+
+ combined_edges = np.maximum(normal_edges, depth_edges)
+
+ sketch_image = torch.from_numpy(combined_edges).to(normal_image.device).float() / 255.0
+ sketch_image = sketch_image.unsqueeze(-1)
+
+ return sketch_image
+
+ def render_sketch_from_depth(self, depth_image):
+ """
+ Generate sketch-style edge image from depth map using edge detection.
+
+ Args:
+ depth_image: Input depth map tensor
+
+ Returns:
+ Binary edge sketch image as tensor
+ """
+ depth_image_np = depth_image.cpu().numpy()
+ depth_image_np = (depth_image_np * 255).astype(np.uint8)
+ depth_edges = cv2.Canny(depth_image_np, 30, 80)
+ combined_edges = depth_edges
+ sketch_image = torch.from_numpy(combined_edges).to(depth_image.device).float() / 255.0
+ sketch_image = sketch_image.unsqueeze(-1)
+ return sketch_image
+
+ def back_project(self, image, elev, azim, camera_distance=None, center=None, method=None):
+ """
+ Back-project a rendered image onto the mesh's UV texture space.
+ Handles visibility, viewing angle, and boundary detection for texture baking.
+
+ Args:
+ image: Input image to back-project (PIL Image, numpy array, or tensor)
+ elev: Camera elevation angle in degrees used for rendering
+ azim: Camera azimuth angle in degrees used for rendering
+ camera_distance: Camera distance (uses default if None)
+ center: Camera focus center (uses origin if None)
+ method: Back-projection method ("linear", "mip-map", "back_sample", uses default if None)
+
+ Returns:
+ Tuple of (texture, cosine_map, boundary_map) tensors in UV space
+ """
+
+ if isinstance(image, Image.Image):
+ image = torch.tensor(np.array(image) / 255.0)
+ elif isinstance(image, np.ndarray):
+ image = torch.tensor(image)
+ if image.dim() == 2:
+ image = image.unsqueeze(-1)
+ image = image.float().to(self.device)
+ resolution = image.shape[:2]
+ channel = image.shape[-1]
+ texture = torch.zeros(self.texture_size + (channel,)).to(self.device)
+ cos_map = torch.zeros(self.texture_size + (1,)).to(self.device)
+
+ proj = self.camera_proj_mat
+ r_mv = get_mv_matrix(
+ elev=elev,
+ azim=azim,
+ camera_distance=self.camera_distance if camera_distance is None else camera_distance,
+ center=center,
+ )
+ pos_camera = transform_pos(r_mv, self.vtx_pos, keepdim=True)
+ pos_clip = transform_pos(proj, pos_camera)
+ pos_camera = pos_camera[:, :3] / pos_camera[:, 3:4]
+
+ v0 = pos_camera[self.pos_idx[:, 0], :]
+ v1 = pos_camera[self.pos_idx[:, 1], :]
+ v2 = pos_camera[self.pos_idx[:, 2], :]
+ face_normals = F.normalize(torch.cross(v1 - v0, v2 - v0, dim=-1), dim=-1)
+
+ tex_depth = pos_camera[:, 2].reshape(1, -1, 1).contiguous()
+ rast_out, rast_out_db = self.raster_rasterize(pos_clip, self.pos_idx, resolution=resolution)
+ visible_mask = torch.clamp(rast_out[..., -1:], 0, 1)[0, ...]
+
+ if self.shader_type == "vertex":
+ vertex_normals = trimesh.geometry.mean_vertex_normals(
+ vertex_count=self.vtx_pos.shape[0],
+ faces=self.pos_idx.cpu(),
+ face_normals=face_normals.cpu(),
+ )
+ vertex_normals = torch.from_numpy(vertex_normals).float().to(self.device).contiguous()
+ normal, _ = self.raster_interpolate(vertex_normals[None, ...], rast_out, self.pos_idx)
+ elif self.shader_type == "face":
+ tri_ids = rast_out[..., 3]
+ tri_ids_mask = tri_ids > 0
+ tri_ids = ((tri_ids - 1) * tri_ids_mask).long()
+ normal = torch.zeros(rast_out.shape[0], rast_out.shape[1], rast_out.shape[2], 3).to(rast_out)
+ normal.reshape(-1, 3)[tri_ids_mask.view(-1)] = face_normals.reshape(-1, 3)[tri_ids[tri_ids_mask].view(-1)]
+
+ normal = normal[0, ...]
+ uv, _ = self.raster_interpolate(self.vtx_uv[None, ...], rast_out, self.uv_idx)
+ depth, _ = self.raster_interpolate(tex_depth, rast_out, self.pos_idx)
+ depth = depth[0, ...]
+
+ depth_max, depth_min = depth[visible_mask > 0].max(), depth[visible_mask > 0].min()
+ depth_normalized = (depth - depth_min) / (depth_max - depth_min)
+ depth_image = depth_normalized * visible_mask # Mask out background.
+
+ sketch_image = self.render_sketch_from_depth(depth_image)
+
+ lookat = torch.tensor([[0, 0, -1]], device=self.device)
+ cos_image = torch.nn.functional.cosine_similarity(lookat, normal.view(-1, 3))
+ cos_image = cos_image.view(normal.shape[0], normal.shape[1], 1)
+
+ cos_thres = np.cos(self.bake_angle_thres / 180 * np.pi)
+ cos_image[cos_image < cos_thres] = 0
+
+ # shrink
+ if self.bake_unreliable_kernel_size > 0:
+ kernel_size = self.bake_unreliable_kernel_size * 2 + 1
+ kernel = torch.ones((1, 1, kernel_size, kernel_size), dtype=torch.float32).to(sketch_image.device)
+
+ visible_mask = visible_mask.permute(2, 0, 1).unsqueeze(0).float()
+ visible_mask = F.conv2d(1.0 - visible_mask, kernel, padding=kernel_size // 2)
+ visible_mask = 1.0 - (visible_mask > 0).float() # 二值化
+ visible_mask = visible_mask.squeeze(0).permute(1, 2, 0)
+
+ sketch_image = sketch_image.permute(2, 0, 1).unsqueeze(0)
+ sketch_image = F.conv2d(sketch_image, kernel, padding=kernel_size // 2)
+ sketch_image = (sketch_image > 0).float() # 二值化
+ sketch_image = sketch_image.squeeze(0).permute(1, 2, 0)
+ visible_mask = visible_mask * (sketch_image < 0.5)
+
+ cos_image[visible_mask == 0] = 0
+
+ method = self.bake_mode if method is None else method
+
+ if method == "linear":
+ proj_mask = (visible_mask != 0).view(-1)
+ uv = uv.squeeze(0).contiguous().view(-1, 2)[proj_mask]
+ image = image.squeeze(0).contiguous().view(-1, channel)[proj_mask]
+ cos_image = cos_image.contiguous().view(-1, 1)[proj_mask]
+ sketch_image = sketch_image.contiguous().view(-1, 1)[proj_mask]
+
+ texture = linear_grid_put_2d(self.texture_size[1], self.texture_size[0], uv[..., [1, 0]], image)
+ cos_map = linear_grid_put_2d(self.texture_size[1], self.texture_size[0], uv[..., [1, 0]], cos_image)
+ boundary_map = linear_grid_put_2d(self.texture_size[1], self.texture_size[0], uv[..., [1, 0]], sketch_image)
+ elif method == "mip-map":
+ proj_mask = (visible_mask != 0).view(-1)
+ uv = uv.squeeze(0).contiguous().view(-1, 2)[proj_mask]
+ image = image.squeeze(0).contiguous().view(-1, channel)[proj_mask]
+ cos_image = cos_image.contiguous().view(-1, 1)[proj_mask]
+
+ texture = mipmap_linear_grid_put_2d(
+ self.texture_size[1], self.texture_size[0], uv[..., [1, 0]], image, min_resolution=128
+ )
+ cos_map = mipmap_linear_grid_put_2d(
+ self.texture_size[1], self.texture_size[0], uv[..., [1, 0]], cos_image, min_resolution=256
+ )
+
+ if self.vtx_map is not None:
+ vertex_normals = vertex_normals[self.vtx_map, :]
+ normal_map = self.uv_feature_map(vertex_normals)
+ cos_map_uv = torch.nn.functional.cosine_similarity(lookat, normal_map.view(-1, 3)) # .abs()
+ cos_map_uv = cos_map_uv.view(1, 1, normal_map.shape[0], normal_map.shape[1])
+ cos_map_uv = torch.nn.functional.max_pool2d(cos_map_uv, kernel_size=3, stride=1, padding=1)
+ cos_map_uv = cos_map_uv.reshape(self.texture_size[0], self.texture_size[1], 1)
+ cos_map_uv[cos_map_uv < cos_thres] = 0
+ # cos_map = torch.min(cos_map, cos_map_uv)
+ cos_map[cos_map_uv < cos_thres] = 0
+ elif method == "back_sample":
+
+ img_proj = torch.from_numpy(
+ np.array(((proj[0, 0], 0, 0, 0), (0, proj[1, 1], 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)))
+ ).to(self.tex_position)
+ w2c = torch.from_numpy(r_mv).to(self.tex_position)
+ v_proj = self.tex_position @ w2c.T @ img_proj
+ inner_mask = (v_proj[:, 0] <= 1.0) & (v_proj[:, 0] >= -1.0) & (v_proj[:, 1] <= 1.0) & (v_proj[:, 1] >= -1.0)
+ inner_valid_idx = torch.where(inner_mask)[0].long()
+ img_x = torch.clamp(
+ ((v_proj[:, 0].clamp(-1, 1) * 0.5 + 0.5) * (resolution[0])).long(), 0, resolution[0] - 1
+ )
+ img_y = torch.clamp(
+ ((v_proj[:, 1].clamp(-1, 1) * 0.5 + 0.5) * (resolution[1])).long(), 0, resolution[1] - 1
+ )
+
+ indices = img_y * resolution[0] + img_x
+ sampled_z = depth.reshape(-1)[indices]
+ sampled_m = visible_mask.reshape(-1)[indices]
+ v_z = v_proj[:, 2]
+
+ sampled_w = cos_image.reshape(-1)[indices]
+ depth_thres = 3e-3
+
+ # valid_idx = torch.where((torch.abs(v_z - sampled_z) < depth_thres) * (sampled_m*sampled_w>0))[0]
+ valid_idx = torch.where((torch.abs(v_z - sampled_z) < depth_thres) & (sampled_m * sampled_w > 0))[0]
+
+ intersection_mask = torch.isin(valid_idx, inner_valid_idx)
+ valid_idx = valid_idx[intersection_mask].to(inner_valid_idx)
+
+ indices = indices[valid_idx]
+ sampled_b = sketch_image.reshape(-1)[indices]
+ sampled_w = sampled_w[valid_idx]
+
+ # bilinear sampling rgb
+ wx = ((v_proj[:, 0] * 0.5 + 0.5) * resolution[0] - img_x)[valid_idx].reshape(-1, 1)
+ wy = ((v_proj[:, 1] * 0.5 + 0.5) * resolution[1] - img_y)[valid_idx].reshape(-1, 1)
+ img_x = img_x[valid_idx]
+ img_y = img_y[valid_idx]
+ img_x_r = torch.clamp(img_x + 1, 0, resolution[0] - 1)
+ img_y_r = torch.clamp(img_y + 1, 0, resolution[1] - 1)
+ indices_lr = img_y * resolution[0] + img_x_r
+ indices_rl = img_y_r * resolution[0] + img_x
+ indices_rr = img_y_r * resolution[0] + img_x_r
+ rgb = image.reshape(-1, channel)
+ sampled_rgb = (rgb[indices] * (1 - wx) + rgb[indices_lr] * wx) * (1 - wy) + (
+ rgb[indices_rl] * (1 - wx) + rgb[indices_rr] * wx
+ ) * wy
+
+ # return sampled_rgb, sampled_w, sampled_b, valid_idx
+ texture = torch.zeros(self.texture_size[0], self.texture_size[1], channel, device=self.device).reshape(
+ -1, channel
+ )
+ cos_map = torch.zeros(self.texture_size[0], self.texture_size[1], 1, device=self.device).reshape(-1)
+ boundary_map = torch.zeros(self.texture_size[0], self.texture_size[1], 1, device=self.device).reshape(-1)
+
+ valid_tex_indices = self.tex_grid[valid_idx, 0] * self.texture_size[1] + self.tex_grid[valid_idx, 1]
+ texture[valid_tex_indices, :] = sampled_rgb
+ cos_map[valid_tex_indices] = sampled_w
+ boundary_map[valid_tex_indices] = sampled_b
+
+ texture = texture.view(self.texture_size[0], self.texture_size[1], channel)
+ cos_map = cos_map.view(self.texture_size[0], self.texture_size[1], 1)
+ # texture = torch.clamp(texture,0,1)
+
+ else:
+ raise f"No bake mode {method}"
+ return texture, cos_map, boundary_map
+
+ def bake_texture(self, colors, elevs, azims, camera_distance=None, center=None, exp=6, weights=None):
+ """
+ Bake multiple view images into a single UV texture using weighted blending.
+
+ Args:
+ colors: List of input images (tensors, numpy arrays, or PIL Images)
+ elevs: List of elevation angles for each view
+ azims: List of azimuth angles for each view
+ camera_distance: Camera distance (uses default if None)
+ center: Camera focus center (uses origin if None)
+ exp: Exponent for cosine weighting (higher values favor front-facing views)
+ weights: Optional per-view weights (defaults to 1.0 for all views)
+
+ Returns:
+ Tuple of (merged_texture, trust_map) tensors in UV space
+ """
+ if isinstance(colors, torch.Tensor):
+ colors = [colors[i, ...].float().permute(1, 2, 0) for i in range(colors.shape[0])]
+ else:
+ for i in range(len(colors)):
+ if isinstance(colors[i], Image.Image):
+ colors[i] = torch.tensor(np.array(colors[i]) / 255.0, device=self.device).float()
+ if weights is None:
+ weights = [1.0 for _ in range(len(colors))]
+ textures = []
+ cos_maps = []
+ for color, elev, azim, weight in zip(colors, elevs, azims, weights):
+ texture, cos_map, _ = self.back_project(color, elev, azim, camera_distance, center)
+ cos_map = weight * (cos_map**exp)
+ textures.append(texture)
+ cos_maps.append(cos_map)
+
+ texture_merge, trust_map_merge = self.fast_bake_texture(textures, cos_maps)
+ return texture_merge, trust_map_merge
+
+ @torch.no_grad()
+ def fast_bake_texture(self, textures, cos_maps):
+ """
+ Efficiently merge multiple textures using cosine-weighted blending.
+ Optimizes by skipping views that don't contribute new information.
+
+ Args:
+ textures: List of texture tensors to merge
+ cos_maps: List of corresponding cosine weight maps
+
+ Returns:
+ Tuple of (merged_texture, valid_mask) tensors
+ """
+
+ channel = textures[0].shape[-1]
+ texture_merge = torch.zeros(self.texture_size + (channel,)).to(self.device)
+ trust_map_merge = torch.zeros(self.texture_size + (1,)).to(self.device)
+ for texture, cos_map in zip(textures, cos_maps):
+ view_sum = (cos_map > 0).sum()
+ painted_sum = ((cos_map > 0) * (trust_map_merge > 0)).sum()
+ if painted_sum / view_sum > 0.99:
+ continue
+ texture_merge += texture * cos_map
+ trust_map_merge += cos_map
+ texture_merge = texture_merge / torch.clamp(trust_map_merge, min=1e-8)
+
+ return texture_merge, trust_map_merge > 1e-8
+
+ @torch.no_grad()
+ def uv_inpaint(self, texture, mask, vertex_inpaint=True, method="NS", return_float=False):
+ """
+ Inpaint missing regions in UV texture using mesh-aware and traditional methods.
+
+ Args:
+ texture: Input texture as tensor, numpy array, or PIL Image
+ mask: Binary mask indicating regions to inpaint (1 = keep, 0 = inpaint)
+ vertex_inpaint: Whether to use mesh vertex connectivity for inpainting
+ method: Inpainting method ("NS" for Navier-Stokes)
+ return_float: Whether to return float values (False returns uint8)
+
+ Returns:
+ Inpainted texture as numpy array
+ """
+
+ if isinstance(texture, torch.Tensor):
+ texture_np = texture.cpu().numpy()
+ elif isinstance(texture, np.ndarray):
+ texture_np = texture
+ elif isinstance(texture, Image.Image):
+ texture_np = np.array(texture) / 255.0
+
+ if isinstance(mask, torch.Tensor):
+ mask = (mask.squeeze(-1).cpu().numpy() * 255).astype(np.uint8)
+
+ if vertex_inpaint:
+ vtx_pos, pos_idx, vtx_uv, uv_idx = self.get_mesh()
+ texture_np, mask = meshVerticeInpaint(texture_np, mask, vtx_pos, vtx_uv, pos_idx, uv_idx)
+
+ if method == "NS":
+ texture_np = cv2.inpaint((texture_np * 255).astype(np.uint8), 255 - mask, 3, cv2.INPAINT_NS)
+ assert return_float == False
+
+ return texture_np
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/__init__.py b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/camera_utils.py b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/camera_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..54369b557b23c7481ed0bbcff25840eb0802cfbf
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/camera_utils.py
@@ -0,0 +1,107 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import math
+
+import numpy as np
+import torch
+
+
+def transform_pos(mtx, pos, keepdim=False):
+ t_mtx = torch.from_numpy(mtx).to(pos.device) if isinstance(mtx, np.ndarray) else mtx
+ if pos.shape[-1] == 3:
+ posw = torch.cat([pos, torch.ones([pos.shape[0], 1]).to(pos.device)], axis=1)
+ else:
+ posw = pos
+
+ if keepdim:
+ return torch.matmul(posw, t_mtx.t())[...]
+ else:
+ return torch.matmul(posw, t_mtx.t())[None, ...]
+
+
+def get_mv_matrix(elev, azim, camera_distance, center=None):
+ elev = -elev
+ azim += 90
+
+ elev_rad = math.radians(elev)
+ azim_rad = math.radians(azim)
+
+ camera_position = np.array(
+ [
+ camera_distance * math.cos(elev_rad) * math.cos(azim_rad),
+ camera_distance * math.cos(elev_rad) * math.sin(azim_rad),
+ camera_distance * math.sin(elev_rad),
+ ]
+ )
+
+ if center is None:
+ center = np.array([0, 0, 0])
+ else:
+ center = np.array(center)
+
+ lookat = center - camera_position
+ lookat = lookat / np.linalg.norm(lookat)
+
+ up = np.array([0, 0, 1.0])
+ right = np.cross(lookat, up)
+ right = right / np.linalg.norm(right)
+ up = np.cross(right, lookat)
+ up = up / np.linalg.norm(up)
+
+ c2w = np.concatenate([np.stack([right, up, -lookat], axis=-1), camera_position[:, None]], axis=-1)
+
+ w2c = np.zeros((4, 4))
+ w2c[:3, :3] = np.transpose(c2w[:3, :3], (1, 0))
+ w2c[:3, 3:] = -np.matmul(np.transpose(c2w[:3, :3], (1, 0)), c2w[:3, 3:])
+ w2c[3, 3] = 1.0
+
+ return w2c.astype(np.float32)
+
+
+def get_orthographic_projection_matrix(left=-1, right=1, bottom=-1, top=1, near=0, far=2):
+ """
+ 计算正交投影矩阵。
+
+ 参数:
+ left (float): 投影区域左侧边界。
+ right (float): 投影区域右侧边界。
+ bottom (float): 投影区域底部边界。
+ top (float): 投影区域顶部边界。
+ near (float): 投影区域近裁剪面距离。
+ far (float): 投影区域远裁剪面距离。
+
+ 返回:
+ numpy.ndarray: 正交投影矩阵。
+ """
+ ortho_matrix = np.eye(4, dtype=np.float32)
+ ortho_matrix[0, 0] = 2 / (right - left)
+ ortho_matrix[1, 1] = 2 / (top - bottom)
+ ortho_matrix[2, 2] = -2 / (far - near)
+ ortho_matrix[0, 3] = -(right + left) / (right - left)
+ ortho_matrix[1, 3] = -(top + bottom) / (top - bottom)
+ ortho_matrix[2, 3] = -(far + near) / (far - near)
+ return ortho_matrix
+
+
+def get_perspective_projection_matrix(fovy, aspect_wh, near, far):
+ fovy_rad = math.radians(fovy)
+ return np.array(
+ [
+ [1.0 / (math.tan(fovy_rad / 2.0) * aspect_wh), 0, 0, 0],
+ [0, 1.0 / math.tan(fovy_rad / 2.0), 0, 0],
+ [0, 0, -(far + near) / (far - near), -2.0 * far * near / (far - near)],
+ [0, 0, -1, 0],
+ ]
+ ).astype(np.float32)
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/compile_mesh_painter.sh b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/compile_mesh_painter.sh
new file mode 100644
index 0000000000000000000000000000000000000000..cf24fb32b51edfda7c9e19cb11c1f72ccb95b68c
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/compile_mesh_painter.sh
@@ -0,0 +1 @@
+c++ -O3 -Wall -shared -std=c++11 -fPIC `python -m pybind11 --includes` mesh_inpaint_processor.cpp -o mesh_inpaint_processor`python3-config --extension-suffix`
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_inpaint_processor.cpp b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_inpaint_processor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..25678713d95eb185b39a0fc6a3c88910e61f32bf
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_inpaint_processor.cpp
@@ -0,0 +1,395 @@
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+namespace py = pybind11;
+using namespace std;
+
+namespace {
+// 内部数据结构,避免重复的buffer获取和指针设置
+struct MeshData {
+ int texture_height, texture_width, texture_channel;
+ int vtx_num;
+ float* texture_ptr;
+ uint8_t* mask_ptr;
+ float* vtx_pos_ptr;
+ float* vtx_uv_ptr;
+ int* pos_idx_ptr;
+ int* uv_idx_ptr;
+
+ // 存储buffer以防止被销毁
+ py::buffer_info texture_buf, mask_buf, vtx_pos_buf, vtx_uv_buf, pos_idx_buf, uv_idx_buf;
+
+ MeshData(py::array_t& texture, py::array_t& mask,
+ py::array_t& vtx_pos, py::array_t& vtx_uv,
+ py::array_t& pos_idx, py::array_t& uv_idx) {
+
+ texture_buf = texture.request();
+ mask_buf = mask.request();
+ vtx_pos_buf = vtx_pos.request();
+ vtx_uv_buf = vtx_uv.request();
+ pos_idx_buf = pos_idx.request();
+ uv_idx_buf = uv_idx.request();
+
+ texture_height = texture_buf.shape[0];
+ texture_width = texture_buf.shape[1];
+ texture_channel = texture_buf.shape[2];
+ texture_ptr = static_cast(texture_buf.ptr);
+ mask_ptr = static_cast(mask_buf.ptr);
+
+ vtx_num = vtx_pos_buf.shape[0];
+ vtx_pos_ptr = static_cast(vtx_pos_buf.ptr);
+ vtx_uv_ptr = static_cast(vtx_uv_buf.ptr);
+ pos_idx_ptr = static_cast(pos_idx_buf.ptr);
+ uv_idx_ptr = static_cast(uv_idx_buf.ptr);
+ }
+};
+
+// 公共函数:计算UV坐标
+pair calculateUVCoordinates(int vtx_uv_idx, const MeshData& data) {
+ int uv_v = round(data.vtx_uv_ptr[vtx_uv_idx * 2] * (data.texture_width - 1));
+ int uv_u = round((1.0 - data.vtx_uv_ptr[vtx_uv_idx * 2 + 1]) * (data.texture_height - 1));
+ return make_pair(uv_u, uv_v);
+}
+
+// 公共函数:计算距离权重
+float calculateDistanceWeight(const array& vtx_0, const array& vtx1) {
+ float dist_weight = 1.0f / max(
+ sqrt(
+ pow(vtx_0[0] - vtx1[0], 2) +
+ pow(vtx_0[1] - vtx1[1], 2) +
+ pow(vtx_0[2] - vtx1[2], 2)
+ ), 1E-4);
+ return dist_weight * dist_weight;
+}
+
+// 公共函数:获取顶点位置
+array getVertexPosition(int vtx_idx, const MeshData& data) {
+ return {data.vtx_pos_ptr[vtx_idx * 3],
+ data.vtx_pos_ptr[vtx_idx * 3 + 1],
+ data.vtx_pos_ptr[vtx_idx * 3 + 2]};
+}
+
+// 公共函数:构建图结构
+void buildGraph(vector>& G, const MeshData& data) {
+ G.resize(data.vtx_num);
+ for(int i = 0; i < data.uv_idx_buf.shape[0]; ++i) {
+ for(int k = 0; k < 3; ++k) {
+ G[data.pos_idx_ptr[i * 3 + k]].push_back(data.pos_idx_ptr[i * 3 + (k + 1) % 3]);
+ }
+ }
+}
+
+// 通用初始化函数:处理两种掩码类型(float和int)
+template
+void initializeVertexDataGeneric(const MeshData& data, vector& vtx_mask,
+ vector>& vtx_color, vector* uncolored_vtxs = nullptr,
+ MaskType mask_value = static_cast(1)) {
+ vtx_mask.assign(data.vtx_num, static_cast(0));
+ vtx_color.assign(data.vtx_num, vector(data.texture_channel, 0.0f));
+
+ if(uncolored_vtxs) {
+ uncolored_vtxs->clear();
+ }
+
+ for(int i = 0; i < data.uv_idx_buf.shape[0]; ++i) {
+ for(int k = 0; k < 3; ++k) {
+ int vtx_uv_idx = data.uv_idx_ptr[i * 3 + k];
+ int vtx_idx = data.pos_idx_ptr[i * 3 + k];
+ auto uv_coords = calculateUVCoordinates(vtx_uv_idx, data);
+
+ if(data.mask_ptr[uv_coords.first * data.texture_width + uv_coords.second] > 0) {
+ vtx_mask[vtx_idx] = mask_value;
+ for(int c = 0; c < data.texture_channel; ++c) {
+ vtx_color[vtx_idx][c] = data.texture_ptr[(uv_coords.first * data.texture_width +
+ uv_coords.second) * data.texture_channel + c];
+ }
+ } else if(uncolored_vtxs) {
+ uncolored_vtxs->push_back(vtx_idx);
+ }
+ }
+ }
+}
+
+// 通用平滑算法:支持不同的掩码类型和检查函数
+template
+void performSmoothingAlgorithm(const MeshData& data, const vector>& G,
+ vector& vtx_mask, vector>& vtx_color,
+ const vector& uncolored_vtxs,
+ function is_colored_func,
+ function set_colored_func) {
+ int smooth_count = 2;
+ int last_uncolored_vtx_count = 0;
+
+ while(smooth_count > 0) {
+ int uncolored_vtx_count = 0;
+
+ for(int vtx_idx : uncolored_vtxs) {
+ vector sum_color(data.texture_channel, 0.0f);
+ float total_weight = 0.0f;
+
+ array vtx_0 = getVertexPosition(vtx_idx, data);
+
+ for(int connected_idx : G[vtx_idx]) {
+ if(is_colored_func(vtx_mask[connected_idx])) {
+ array vtx1 = getVertexPosition(connected_idx, data);
+ float dist_weight = calculateDistanceWeight(vtx_0, vtx1);
+
+ for(int c = 0; c < data.texture_channel; ++c) {
+ sum_color[c] += vtx_color[connected_idx][c] * dist_weight;
+ }
+ total_weight += dist_weight;
+ }
+ }
+
+ if(total_weight > 0.0f) {
+ for(int c = 0; c < data.texture_channel; ++c) {
+ vtx_color[vtx_idx][c] = sum_color[c] / total_weight;
+ }
+ set_colored_func(vtx_mask[vtx_idx]);
+ } else {
+ uncolored_vtx_count++;
+ }
+ }
+
+ if(last_uncolored_vtx_count == uncolored_vtx_count) {
+ smooth_count--;
+ } else {
+ smooth_count++;
+ }
+ last_uncolored_vtx_count = uncolored_vtx_count;
+ }
+}
+
+// 前向传播算法的通用实现
+void performForwardPropagation(const MeshData& data, const vector>& G,
+ vector& vtx_mask, vector>& vtx_color,
+ queue& active_vtxs) {
+ while(!active_vtxs.empty()) {
+ queue pending_active_vtxs;
+
+ while(!active_vtxs.empty()) {
+ int vtx_idx = active_vtxs.front();
+ active_vtxs.pop();
+ array vtx_0 = getVertexPosition(vtx_idx, data);
+
+ for(int connected_idx : G[vtx_idx]) {
+ if(vtx_mask[connected_idx] > 0) continue;
+
+ array vtx1 = getVertexPosition(connected_idx, data);
+ float dist_weight = calculateDistanceWeight(vtx_0, vtx1);
+
+ for(int c = 0; c < data.texture_channel; ++c) {
+ vtx_color[connected_idx][c] += vtx_color[vtx_idx][c] * dist_weight;
+ }
+
+ if(vtx_mask[connected_idx] == 0) {
+ pending_active_vtxs.push(connected_idx);
+ }
+ vtx_mask[connected_idx] -= dist_weight;
+ }
+ }
+
+ while(!pending_active_vtxs.empty()) {
+ int vtx_idx = pending_active_vtxs.front();
+ pending_active_vtxs.pop();
+
+ for(int c = 0; c < data.texture_channel; ++c) {
+ vtx_color[vtx_idx][c] /= -vtx_mask[vtx_idx];
+ }
+ vtx_mask[vtx_idx] = 1.0f;
+ active_vtxs.push(vtx_idx);
+ }
+ }
+}
+
+// 公共函数:创建输出数组
+pair, py::array_t> createOutputArrays(
+ const MeshData& data, const vector& vtx_mask,
+ const vector>& vtx_color) {
+
+ py::array_t new_texture(data.texture_buf.size);
+ py::array_t new_mask(data.mask_buf.size);
+
+ auto new_texture_buf = new_texture.request();
+ auto new_mask_buf = new_mask.request();
+
+ float* new_texture_ptr = static_cast(new_texture_buf.ptr);
+ uint8_t* new_mask_ptr = static_cast(new_mask_buf.ptr);
+
+ // Copy original texture and mask to new arrays
+ copy(data.texture_ptr, data.texture_ptr + data.texture_buf.size, new_texture_ptr);
+ copy(data.mask_ptr, data.mask_ptr + data.mask_buf.size, new_mask_ptr);
+
+ for(int face_idx = 0; face_idx < data.uv_idx_buf.shape[0]; ++face_idx) {
+ for(int k = 0; k < 3; ++k) {
+ int vtx_uv_idx = data.uv_idx_ptr[face_idx * 3 + k];
+ int vtx_idx = data.pos_idx_ptr[face_idx * 3 + k];
+
+ if(vtx_mask[vtx_idx] == 1.0f) {
+ auto uv_coords = calculateUVCoordinates(vtx_uv_idx, data);
+
+ for(int c = 0; c < data.texture_channel; ++c) {
+ new_texture_ptr[
+ (uv_coords.first * data.texture_width + uv_coords.second) *
+ data.texture_channel + c
+ ] = vtx_color[vtx_idx][c];
+ }
+ new_mask_ptr[uv_coords.first * data.texture_width + uv_coords.second] = 255;
+ }
+ }
+ }
+
+ // Reshape the new arrays to match the original texture and mask shapes
+ new_texture.resize({data.texture_height, data.texture_width, 3});
+ new_mask.resize({data.texture_height, data.texture_width});
+
+ return make_pair(new_texture, new_mask);
+}
+
+// 创建顶点颜色输出数组的专用函数
+pair, py::array_t> createVertexColorOutput(
+ const MeshData& data, const vector& vtx_mask,
+ const vector>& vtx_color) {
+
+ py::array_t py_vtx_color({data.vtx_num, data.texture_channel});
+ py::array_t py_vtx_mask({data.vtx_num});
+
+ auto py_vtx_color_buf = py_vtx_color.request();
+ auto py_vtx_mask_buf = py_vtx_mask.request();
+
+ float* py_vtx_color_ptr = static_cast(py_vtx_color_buf.ptr);
+ uint8_t* py_vtx_mask_ptr = static_cast(py_vtx_mask_buf.ptr);
+
+ for(int i = 0; i < data.vtx_num; ++i) {
+ py_vtx_mask_ptr[i] = vtx_mask[i];
+ for(int c = 0; c < data.texture_channel; ++c) {
+ py_vtx_color_ptr[i * data.texture_channel + c] = vtx_color[i][c];
+ }
+ }
+
+ return make_pair(py_vtx_color, py_vtx_mask);
+}
+
+} // anonymous namespace
+
+// 重构后的 meshVerticeInpaint_smooth 函数
+pair, py::array_t> meshVerticeInpaint_smooth(
+ py::array_t texture, py::array_t mask, py::array_t vtx_pos, py::array_t vtx_uv,
+ py::array_t pos_idx, py::array_t uv_idx) {
+
+ MeshData data(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+
+ vector vtx_mask;
+ vector> vtx_color;
+ vector uncolored_vtxs;
+ vector> G;
+
+ initializeVertexDataGeneric(data, vtx_mask, vtx_color, &uncolored_vtxs, 1.0f);
+ buildGraph(G, data);
+
+ // 使用通用平滑算法
+ performSmoothingAlgorithm(data, G, vtx_mask, vtx_color, uncolored_vtxs,
+ [](float mask_val) { return mask_val > 0; }, // 检查是否着色
+ [](float& mask_val) { mask_val = 1.0f; } // 设置为已着色
+ );
+
+ return createOutputArrays(data, vtx_mask, vtx_color);
+}
+
+// 重构后的 meshVerticeInpaint_forward 函数
+pair, py::array_t> meshVerticeInpaint_forward(
+ py::array_t texture, py::array_t mask, py::array_t vtx_pos, py::array_t vtx_uv,
+ py::array_t pos_idx, py::array_t uv_idx) {
+
+ MeshData data(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+
+ vector vtx_mask;
+ vector> vtx_color;
+ vector> G;
+ queue active_vtxs;
+
+ // 使用通用初始化(不需要 uncolored_vtxs)
+ initializeVertexDataGeneric(data, vtx_mask, vtx_color, nullptr, 1.0f);
+ buildGraph(G, data);
+
+ // 收集活跃顶点
+ for(int i = 0; i < data.vtx_num; ++i) {
+ if(vtx_mask[i] == 1.0f) {
+ active_vtxs.push(i);
+ }
+ }
+
+ // 使用通用前向传播算法
+ performForwardPropagation(data, G, vtx_mask, vtx_color, active_vtxs);
+
+ return createOutputArrays(data, vtx_mask, vtx_color);
+}
+
+// 主接口函数
+pair, py::array_t> meshVerticeInpaint(
+ py::array_t texture, py::array_t mask, py::array_t vtx_pos, py::array_t vtx_uv,
+ py::array_t pos_idx, py::array_t uv_idx, const string& method = "smooth") {
+
+ if(method == "smooth") {
+ return meshVerticeInpaint_smooth(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+ } else if(method == "forward") {
+ return meshVerticeInpaint_forward(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+ } else {
+ throw invalid_argument("Invalid method. Use 'smooth' or 'forward'.");
+ }
+}
+
+//============================
+
+// 重构后的 meshVerticeColor_smooth 函数
+pair, py::array_t> meshVerticeColor_smooth(
+ py::array_t texture, py::array_t mask, py::array_t vtx_pos, py::array_t vtx_uv,
+ py::array_t pos_idx, py::array_t uv_idx) {
+
+ MeshData data(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+
+ vector vtx_mask;
+ vector> vtx_color;
+ vector uncolored_vtxs;
+ vector> G;
+
+ initializeVertexDataGeneric(data, vtx_mask, vtx_color, &uncolored_vtxs, 1);
+ buildGraph(G, data);
+
+ // 使用通用平滑算法
+ performSmoothingAlgorithm(data, G, vtx_mask, vtx_color, uncolored_vtxs,
+ [](int mask_val) { return mask_val > 0; }, // 检查是否着色
+ [](int& mask_val) { mask_val = 2; } // 设置为已着色(值为2)
+ );
+
+ return createVertexColorOutput(data, vtx_mask, vtx_color);
+}
+
+// meshVerticeColor 主接口函数
+pair, py::array_t> meshVerticeColor(
+ py::array_t texture, py::array_t mask, py::array_t vtx_pos, py::array_t vtx_uv,
+ py::array_t pos_idx, py::array_t uv_idx, const string& method = "smooth") {
+
+ if(method == "smooth") {
+ return meshVerticeColor_smooth(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
+ } else {
+ throw invalid_argument("Invalid method. Use 'smooth' or 'forward'.");
+ }
+}
+
+// Python绑定
+PYBIND11_MODULE(mesh_inpaint_processor, m) {
+ m.def("meshVerticeInpaint", &meshVerticeInpaint, "A function to process mesh",
+ py::arg("texture"), py::arg("mask"), py::arg("vtx_pos"), py::arg("vtx_uv"),
+ py::arg("pos_idx"), py::arg("uv_idx"), py::arg("method") = "smooth");
+ m.def("meshVerticeColor", &meshVerticeColor, "A function to process mesh",
+ py::arg("texture"), py::arg("mask"), py::arg("vtx_pos"), py::arg("vtx_uv"),
+ py::arg("pos_idx"), py::arg("uv_idx"), py::arg("method") = "smooth");
+}
diff --git a/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_utils.py b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b3e8317b7b8e8e3a293532cc278ede157d88e07
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer/mesh_utils.py
@@ -0,0 +1,284 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import cv2
+import bpy
+import math
+import numpy as np
+from io import StringIO
+from typing import Optional, Tuple, Dict, Any
+
+
+def _safe_extract_attribute(obj: Any, attr_path: str, default: Any = None) -> Any:
+ """Extract nested attribute safely from object."""
+ try:
+ for attr in attr_path.split("."):
+ obj = getattr(obj, attr)
+ return obj
+ except AttributeError:
+ return default
+
+
+def _convert_to_numpy(data: Any, dtype: np.dtype) -> Optional[np.ndarray]:
+ """Convert data to numpy array with specified dtype, handling None values."""
+ if data is None:
+ return None
+ return np.asarray(data, dtype=dtype)
+
+
+def load_mesh(mesh):
+ """Load mesh data including vertices, faces, UV coordinates and texture."""
+ # Extract vertex positions and face indices
+ vtx_pos = _safe_extract_attribute(mesh, "vertices")
+ pos_idx = _safe_extract_attribute(mesh, "faces")
+
+ # Extract UV coordinates (reusing face indices for UV indices)
+ vtx_uv = _safe_extract_attribute(mesh, "visual.uv")
+ uv_idx = pos_idx # Reuse face indices for UV mapping
+
+ # Convert to numpy arrays with appropriate dtypes
+ vtx_pos = _convert_to_numpy(vtx_pos, np.float32)
+ pos_idx = _convert_to_numpy(pos_idx, np.int32)
+ vtx_uv = _convert_to_numpy(vtx_uv, np.float32)
+ uv_idx = _convert_to_numpy(uv_idx, np.int32)
+
+ texture_data = None
+ return vtx_pos, pos_idx, vtx_uv, uv_idx, texture_data
+
+
+def _get_base_path_and_name(mesh_path: str) -> Tuple[str, str]:
+ """Get base path without extension and mesh name."""
+ base_path = os.path.splitext(mesh_path)[0]
+ name = os.path.basename(base_path)
+ return base_path, name
+
+
+def _save_texture_map(
+ texture: np.ndarray,
+ base_path: str,
+ suffix: str = "",
+ image_format: str = ".jpg",
+ color_convert: Optional[int] = None,
+) -> str:
+ """Save texture map with optional color conversion."""
+ path = f"{base_path}{suffix}{image_format}"
+ processed_texture = (texture * 255).astype(np.uint8)
+
+ if color_convert is not None:
+ processed_texture = cv2.cvtColor(processed_texture, color_convert)
+ cv2.imwrite(path, processed_texture)
+ else:
+ cv2.imwrite(path, processed_texture[..., ::-1]) # RGB to BGR
+
+ return os.path.basename(path)
+
+
+def _write_mtl_properties(f, properties: Dict[str, Any]):
+ """Write material properties to MTL file."""
+ for key, value in properties.items():
+ if isinstance(value, (list, tuple)):
+ f.write(f"{key} {' '.join(map(str, value))}\n")
+ else:
+ f.write(f"{key} {value}\n")
+
+
+def _create_obj_content(
+ vtx_pos: np.ndarray, vtx_uv: np.ndarray, pos_idx: np.ndarray, uv_idx: np.ndarray, name: str
+) -> str:
+ """Create OBJ file content."""
+ buffer = StringIO()
+
+ # Write header and vertices
+ buffer.write(f"mtllib {name}.mtl\no {name}\n")
+ np.savetxt(buffer, vtx_pos, fmt="v %.6f %.6f %.6f")
+ np.savetxt(buffer, vtx_uv, fmt="vt %.6f %.6f")
+ buffer.write("s 0\nusemtl Material\n")
+
+ # Write faces
+ pos_idx_plus1 = pos_idx + 1
+ uv_idx_plus1 = uv_idx + 1
+ face_format = np.frompyfunc(lambda *x: f"{int(x[0])}/{int(x[1])}", 2, 1)
+ faces = face_format(pos_idx_plus1, uv_idx_plus1)
+ face_strings = [f"f {' '.join(face)}" for face in faces]
+ buffer.write("\n".join(face_strings) + "\n")
+
+ return buffer.getvalue()
+
+
+def save_obj_mesh(mesh_path, vtx_pos, pos_idx, vtx_uv, uv_idx, texture, metallic=None, roughness=None, normal=None):
+ """Save mesh as OBJ file with textures and material."""
+ # Convert inputs to numpy arrays
+ vtx_pos = _convert_to_numpy(vtx_pos, np.float32)
+ vtx_uv = _convert_to_numpy(vtx_uv, np.float32)
+ pos_idx = _convert_to_numpy(pos_idx, np.int32)
+ uv_idx = _convert_to_numpy(uv_idx, np.int32)
+
+ base_path, name = _get_base_path_and_name(mesh_path)
+
+ # Create and save OBJ content
+ obj_content = _create_obj_content(vtx_pos, vtx_uv, pos_idx, uv_idx, name)
+ with open(mesh_path, "w") as obj_file:
+ obj_file.write(obj_content)
+
+ # Save texture maps
+ texture_maps = {}
+ texture_maps["diffuse"] = _save_texture_map(texture, base_path)
+
+ if metallic is not None:
+ texture_maps["metallic"] = _save_texture_map(metallic, base_path, "_metallic", color_convert=cv2.COLOR_RGB2GRAY)
+ if roughness is not None:
+ texture_maps["roughness"] = _save_texture_map(
+ roughness, base_path, "_roughness", color_convert=cv2.COLOR_RGB2GRAY
+ )
+ if normal is not None:
+ texture_maps["normal"] = _save_texture_map(normal, base_path, "_normal")
+
+ # Create MTL file
+ _create_mtl_file(base_path, texture_maps, metallic is not None)
+
+
+def _create_mtl_file(base_path: str, texture_maps: Dict[str, str], is_pbr: bool):
+ """Create MTL material file."""
+ mtl_path = f"{base_path}.mtl"
+
+ with open(mtl_path, "w") as f:
+ f.write("newmtl Material\n")
+
+ if is_pbr:
+ # PBR material properties
+ properties = {
+ "Kd": [0.800, 0.800, 0.800],
+ "Ke": [0.000, 0.000, 0.000], # 鐜鍏夐伄钄�
+ "Ni": 1.500, # 鎶樺皠绯绘暟
+ "d": 1.0, # 閫忔槑搴�
+ "illum": 2, # 鍏夌収妯″瀷
+ "map_Kd": texture_maps["diffuse"],
+ }
+ _write_mtl_properties(f, properties)
+
+ # Additional PBR maps
+ map_configs = [("metallic", "map_Pm"), ("roughness", "map_Pr"), ("normal", "map_Bump -bm 1.0")]
+
+ for texture_key, mtl_key in map_configs:
+ if texture_key in texture_maps:
+ f.write(f"{mtl_key} {texture_maps[texture_key]}\n")
+ else:
+ # Standard material properties
+ properties = {
+ "Ns": 250.000000,
+ "Ka": [0.200, 0.200, 0.200],
+ "Kd": [0.800, 0.800, 0.800],
+ "Ks": [0.500, 0.500, 0.500],
+ "Ke": [0.000, 0.000, 0.000],
+ "Ni": 1.500,
+ "d": 1.0,
+ "illum": 3,
+ "map_Kd": texture_maps["diffuse"],
+ }
+ _write_mtl_properties(f, properties)
+
+
+def save_mesh(mesh_path, vtx_pos, pos_idx, vtx_uv, uv_idx, texture, metallic=None, roughness=None, normal=None):
+ """Save mesh using OBJ format."""
+ save_obj_mesh(
+ mesh_path, vtx_pos, pos_idx, vtx_uv, uv_idx, texture, metallic=metallic, roughness=roughness, normal=normal
+ )
+
+
+def _setup_blender_scene():
+ """Setup Blender scene for conversion."""
+ if "convert" not in bpy.data.scenes:
+ bpy.data.scenes.new("convert")
+ bpy.context.window.scene = bpy.data.scenes["convert"]
+
+
+def _clear_scene_objects():
+ """Clear all objects from current Blender scene."""
+ for obj in bpy.context.scene.objects:
+ obj.select_set(True)
+ bpy.data.objects.remove(obj, do_unlink=True)
+
+
+def _select_mesh_objects():
+ """Select all mesh objects in scene."""
+ bpy.ops.object.select_all(action="DESELECT")
+ for obj in bpy.context.scene.objects:
+ if obj.type == "MESH":
+ obj.select_set(True)
+
+
+def _merge_vertices_if_needed(merge_vertices: bool):
+ """Merge duplicate vertices if requested."""
+ if not merge_vertices:
+ return
+
+ for obj in bpy.context.selected_objects:
+ if obj.type == "MESH":
+ bpy.context.view_layer.objects.active = obj
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_all(action="SELECT")
+ bpy.ops.mesh.remove_doubles()
+ bpy.ops.object.mode_set(mode="OBJECT")
+
+
+def _apply_shading(shade_type: str, auto_smooth_angle: float):
+ """Apply shading to selected objects."""
+ shading_ops = {
+ "SMOOTH": lambda: bpy.ops.object.shade_smooth(),
+ "FLAT": lambda: bpy.ops.object.shade_flat(),
+ "AUTO_SMOOTH": lambda: _apply_auto_smooth(auto_smooth_angle),
+ }
+
+ if shade_type in shading_ops:
+ shading_ops[shade_type]()
+
+
+def _apply_auto_smooth(auto_smooth_angle: float):
+ """Apply auto smooth based on Blender version."""
+ angle_rad = math.radians(auto_smooth_angle)
+
+ if bpy.app.version < (4, 1, 0):
+ bpy.ops.object.shade_smooth(use_auto_smooth=True, auto_smooth_angle=angle_rad)
+ elif bpy.app.version < (4, 2, 0):
+ bpy.ops.object.shade_smooth_by_angle(angle=angle_rad)
+ else:
+ bpy.ops.object.shade_auto_smooth(angle=angle_rad)
+
+
+def convert_obj_to_glb(
+ obj_path: str,
+ glb_path: str,
+ shade_type: str = "SMOOTH",
+ auto_smooth_angle: float = 60,
+ merge_vertices: bool = False,
+) -> bool:
+ """Convert OBJ file to GLB format using Blender."""
+ try:
+ _setup_blender_scene()
+ _clear_scene_objects()
+
+ # Import OBJ file
+ bpy.ops.wm.obj_import(filepath=obj_path)
+ _select_mesh_objects()
+
+ # Process meshes
+ _merge_vertices_if_needed(merge_vertices)
+ _apply_shading(shade_type, auto_smooth_angle)
+
+ # Export to GLB
+ bpy.ops.export_scene.gltf(filepath=glb_path, use_active_scene=True)
+ return True
+ except Exception:
+ return False
diff --git a/Hunyuan3D-2.1/hy3dpaint/LICENSE b/Hunyuan3D-2.1/hy3dpaint/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..96313b341082fb9f72a00b7c77accd8196390af0
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/LICENSE
@@ -0,0 +1,81 @@
+TENCENT HUNYUAN 3D 2.1 COMMUNITY LICENSE AGREEMENT
+Tencent Hunyuan 3D 2.1 Release Date: June 13, 2025
+THIS LICENSE AGREEMENT DOES NOT APPLY IN THE EUROPEAN UNION, UNITED KINGDOM AND SOUTH KOREA AND IS EXPRESSLY LIMITED TO THE TERRITORY, AS DEFINED BELOW.
+By clicking to agree or by using, reproducing, modifying, distributing, performing or displaying any portion or element of the Tencent Hunyuan 3D 2.1 Works, including via any Hosted Service, You will be deemed to have recognized and accepted the content of this Agreement, which is effective immediately.
+1. DEFINITIONS.
+a. “Acceptable Use Policy” shall mean the policy made available by Tencent as set forth in the Exhibit A.
+b. “Agreement” shall mean the terms and conditions for use, reproduction, distribution, modification, performance and displaying of Tencent Hunyuan 3D 2.1 Works or any portion or element thereof set forth herein.
+c. “Documentation” shall mean the specifications, manuals and documentation for Tencent Hunyuan 3D 2.1 made publicly available by Tencent.
+d. “Hosted Service” shall mean a hosted service offered via an application programming interface (API), web access, or any other electronic or remote means.
+e. “Licensee,” “You” or “Your” shall mean a natural person or legal entity exercising the rights granted by this Agreement and/or using the Tencent Hunyuan 3D 2.1 Works for any purpose and in any field of use.
+f. “Materials” shall mean, collectively, Tencent’s proprietary Tencent Hunyuan 3D 2.1 and Documentation (and any portion thereof) as made available by Tencent under this Agreement.
+g. “Model Derivatives” shall mean all: (i) modifications to Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; (ii) works based on Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; or (iii) any other machine learning model which is created by transfer of patterns of the weights, parameters, operations, or Output of Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1, to that model in order to cause that model to perform similarly to Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1, including distillation methods, methods that use intermediate data representations, or methods based on the generation of synthetic data Outputs by Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1 for training that model. For clarity, Outputs by themselves are not deemed Model Derivatives.
+h. “Output” shall mean the information and/or content output of Tencent Hunyuan 3D 2.1 or a Model Derivative that results from operating or otherwise using Tencent Hunyuan 3D 2.1 or a Model Derivative, including via a Hosted Service.
+i. “Tencent,” “We” or “Us” shall mean THL Q Limited.
+j. “Tencent Hunyuan 3D 2.1” shall mean the 3D generation models and their software and algorithms, including trained model weights, parameters (including optimizer states), machine-learning model code, inference-enabling code, training-enabling code, fine-tuning enabling code and other elements of the foregoing made publicly available by Us at [ https://github.com/Tencent-Hunyuan/Hunyuan3D-2.1].
+k. “Tencent Hunyuan 3D 2.1 Works” shall mean: (i) the Materials; (ii) Model Derivatives; and (iii) all derivative works thereof.
+l. “Territory” shall mean the worldwide territory, excluding the territory of the European Union, United Kingdom and South Korea.
+m. “Third Party” or “Third Parties” shall mean individuals or legal entities that are not under common control with Us or You.
+n. “including” shall mean including but not limited to.
+2. GRANT OF RIGHTS.
+We grant You, for the Territory only, a non-exclusive, non-transferable and royalty-free limited license under Tencent’s intellectual property or other rights owned by Us embodied in or utilized by the Materials to use, reproduce, distribute, create derivative works of (including Model Derivatives), and make modifications to the Materials, only in accordance with the terms of this Agreement and the Acceptable Use Policy, and You must not violate (or encourage or permit anyone else to violate) any term of this Agreement or the Acceptable Use Policy.
+3. DISTRIBUTION.
+You may, subject to Your compliance with this Agreement, distribute or make available to Third Parties the Tencent Hunyuan 3D 2.1 Works, exclusively in the Territory, provided that You meet all of the following conditions:
+a. You must provide all such Third Party recipients of the Tencent Hunyuan 3D 2.1 Works or products or services using them a copy of this Agreement;
+b. You must cause any modified files to carry prominent notices stating that You changed the files;
+c. You are encouraged to: (i) publish at least one technology introduction blogpost or one public statement expressing Your experience of using the Tencent Hunyuan 3D 2.1 Works; and (ii) mark the products or services developed by using the Tencent Hunyuan 3D 2.1 Works to indicate that the product/service is “Powered by Tencent Hunyuan”; and
+d. All distributions to Third Parties (other than through a Hosted Service) must be accompanied by a “Notice” text file that contains the following notice: “Tencent Hunyuan 3D 2.1 is licensed under the Tencent Hunyuan 3D 2.1 Community License Agreement, Copyright © 2025 Tencent. All Rights Reserved. The trademark rights of “Tencent Hunyuan” are owned by Tencent or its affiliate.”
+You may add Your own copyright statement to Your modifications and, except as set forth in this Section and in Section 5, may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Model Derivatives as a whole, provided Your use, reproduction, modification, distribution, performance and display of the work otherwise complies with the terms and conditions of this Agreement (including as regards the Territory). If You receive Tencent Hunyuan 3D 2.1 Works from a Licensee as part of an integrated end user product, then this Section 3 of this Agreement will not apply to You.
+4. ADDITIONAL COMMERCIAL TERMS.
+If, on the Tencent Hunyuan 3D 2.1 version release date, the monthly active users of all products or services made available by or for Licensee is greater than 1 million monthly active users in the preceding calendar month, You must request a license from Tencent, which Tencent may grant to You in its sole discretion, and You are not authorized to exercise any of the rights under this Agreement unless or until Tencent otherwise expressly grants You such rights.
+Subject to Tencent's written approval, you may request a license for the use of Tencent Hunyuan 3D 2.1 by submitting the following information to hunyuan3d@tencent.com:
+a. Your company’s name and associated business sector that plans to use Tencent Hunyuan 3D 2.1.
+b. Your intended use case and the purpose of using Tencent Hunyuan 3D 2.1.
+c. Your plans to modify Tencent Hunyuan 3D 2.1 or create Model Derivatives.
+5. RULES OF USE.
+a. Your use of the Tencent Hunyuan 3D 2.1 Works must comply with applicable laws and regulations (including trade compliance laws and regulations) and adhere to the Acceptable Use Policy for the Tencent Hunyuan 3D 2.1 Works, which is hereby incorporated by reference into this Agreement. You must include the use restrictions referenced in these Sections 5(a) and 5(b) as an enforceable provision in any agreement (e.g., license agreement, terms of use, etc.) governing the use and/or distribution of Tencent Hunyuan 3D 2.1 Works and You must provide notice to subsequent users to whom You distribute that Tencent Hunyuan 3D 2.1 Works are subject to the use restrictions in these Sections 5(a) and 5(b).
+b. You must not use the Tencent Hunyuan 3D 2.1 Works or any Output or results of the Tencent Hunyuan 3D 2.1 Works to improve any other AI model (other than Tencent Hunyuan 3D 2.1 or Model Derivatives thereof).
+c. You must not use, reproduce, modify, distribute, or display the Tencent Hunyuan 3D 2.1 Works, Output or results of the Tencent Hunyuan 3D 2.1 Works outside the Territory. Any such use outside the Territory is unlicensed and unauthorized under this Agreement.
+6. INTELLECTUAL PROPERTY.
+a. Subject to Tencent’s ownership of Tencent Hunyuan 3D 2.1 Works made by or for Tencent and intellectual property rights therein, conditioned upon Your compliance with the terms and conditions of this Agreement, as between You and Tencent, You will be the owner of any derivative works and modifications of the Materials and any Model Derivatives that are made by or for You.
+b. No trademark licenses are granted under this Agreement, and in connection with the Tencent Hunyuan 3D 2.1 Works, Licensee may not use any name or mark owned by or associated with Tencent or any of its affiliates, except as required for reasonable and customary use in describing and distributing the Tencent Hunyuan 3D 2.1 Works. Tencent hereby grants You a license to use “Tencent Hunyuan” (the “Mark”) in the Territory solely as required to comply with the provisions of Section 3(c), provided that You comply with any applicable laws related to trademark protection. All goodwill arising out of Your use of the Mark will inure to the benefit of Tencent.
+c. If You commence a lawsuit or other proceedings (including a cross-claim or counterclaim in a lawsuit) against Us or any person or entity alleging that the Materials or any Output, or any portion of any of the foregoing, infringe any intellectual property or other right owned or licensable by You, then all licenses granted to You under this Agreement shall terminate as of the date such lawsuit or other proceeding is filed. You will defend, indemnify and hold harmless Us from and against any claim by any Third Party arising out of or related to Your or the Third Party’s use or distribution of the Tencent Hunyuan 3D 2.1 Works.
+d. Tencent claims no rights in Outputs You generate. You and Your users are solely responsible for Outputs and their subsequent uses.
+7. DISCLAIMERS OF WARRANTY AND LIMITATIONS OF LIABILITY.
+a. We are not obligated to support, update, provide training for, or develop any further version of the Tencent Hunyuan 3D 2.1 Works or to grant any license thereto.
+b. UNLESS AND ONLY TO THE EXTENT REQUIRED BY APPLICABLE LAW, THE TENCENT HUNYUAN 3D 2.1 WORKS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND INCLUDING ANY WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, COURSE OF DEALING, USAGE OF TRADE, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING, REPRODUCING, MODIFYING, PERFORMING, DISPLAYING OR DISTRIBUTING ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND ASSUME ANY AND ALL RISKS ASSOCIATED WITH YOUR OR A THIRD PARTY’S USE OR DISTRIBUTION OF ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND YOUR EXERCISE OF RIGHTS AND PERMISSIONS UNDER THIS AGREEMENT.
+c. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL TENCENT OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, FOR ANY DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, CONSEQUENTIAL OR PUNITIVE DAMAGES, OR LOST PROFITS OF ANY KIND ARISING FROM THIS AGREEMENT OR RELATED TO ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS, EVEN IF TENCENT OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING.
+8. SURVIVAL AND TERMINATION.
+a. The term of this Agreement shall commence upon Your acceptance of this Agreement or access to the Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein.
+b. We may terminate this Agreement if You breach any of the terms or conditions of this Agreement. Upon termination of this Agreement, You must promptly delete and cease use of the Tencent Hunyuan 3D 2.1 Works. Sections 6(a), 6(c), 7 and 9 shall survive the termination of this Agreement.
+9. GOVERNING LAW AND JURISDICTION.
+a. This Agreement and any dispute arising out of or relating to it will be governed by the laws of the Hong Kong Special Administrative Region of the People’s Republic of China, without regard to conflict of law principles, and the UN Convention on Contracts for the International Sale of Goods does not apply to this Agreement.
+b. Exclusive jurisdiction and venue for any dispute arising out of or relating to this Agreement will be a court of competent jurisdiction in the Hong Kong Special Administrative Region of the People’s Republic of China, and Tencent and Licensee consent to the exclusive jurisdiction of such court with respect to any such dispute.
+
+EXHIBIT A
+ACCEPTABLE USE POLICY
+
+Tencent reserves the right to update this Acceptable Use Policy from time to time.
+Last modified: November 5, 2024
+
+Tencent endeavors to promote safe and fair use of its tools and features, including Tencent Hunyuan 3D 2.1. You agree not to use Tencent Hunyuan 3D 2.1 or Model Derivatives:
+1. Outside the Territory;
+2. In any way that violates any applicable national, federal, state, local, international or any other law or regulation;
+3. To harm Yourself or others;
+4. To repurpose or distribute output from Tencent Hunyuan 3D 2.1 or any Model Derivatives to harm Yourself or others;
+5. To override or circumvent the safety guardrails and safeguards We have put in place;
+6. For the purpose of exploiting, harming or attempting to exploit or harm minors in any way;
+7. To generate or disseminate verifiably false information and/or content with the purpose of harming others or influencing elections;
+8. To generate or facilitate false online engagement, including fake reviews and other means of fake online engagement;
+9. To intentionally defame, disparage or otherwise harass others;
+10. To generate and/or disseminate malware (including ransomware) or any other content to be used for the purpose of harming electronic systems;
+11. To generate or disseminate personal identifiable information with the purpose of harming others;
+12. To generate or disseminate information (including images, code, posts, articles), and place the information in any public context (including –through the use of bot generated tweets), without expressly and conspicuously identifying that the information and/or content is machine generated;
+13. To impersonate another individual without consent, authorization, or legal right;
+14. To make high-stakes automated decisions in domains that affect an individual’s safety, rights or wellbeing (e.g., law enforcement, migration, medicine/health, management of critical infrastructure, safety components of products, essential services, credit, employment, housing, education, social scoring, or insurance);
+15. In a manner that violates or disrespects the social ethics and moral standards of other countries or regions;
+16. To perform, facilitate, threaten, incite, plan, promote or encourage violent extremism or terrorism;
+17. For any use intended to discriminate against or harm individuals or groups based on protected characteristics or categories, online or offline social behavior or known or predicted personal or personality characteristics;
+18. To intentionally exploit any of the vulnerabilities of a specific group of persons based on their age, social, physical or mental characteristics, in order to materially distort the behavior of a person pertaining to that group in a manner that causes or is likely to cause that person or another person physical or psychological harm;
+19. For military purposes;
+20. To engage in the unauthorized or unlicensed practice of any profession including, but not limited to, financial, legal, medical/health, or other professional practices.
diff --git a/Hunyuan3D-2.1/hy3dpaint/README.md b/Hunyuan3D-2.1/hy3dpaint/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..70d1bdec760bcd741802737d84a930cf150f53b8
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/README.md
@@ -0,0 +1,96 @@
+# Hunyuan3D-Paint 2.1
+
+Hunyuan3D-Paint 2.1 is a high quality PBR texture generation model for 3D meshes, powered by [RomanTex](https://github.com/oakshy/RomanTex) and [MaterialMVP](https://github.com/ZebinHe/MaterialMVP/).
+
+
+## Quick Inference
+You need to manually download the RealESRGAN weight to the `ckpt` folder using the following command:
+```bash
+wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P ckpt
+```
+
+Given a 3D mesh `mesh.glb` and a reference image `image.png`, you can run inference using the following code. The result will be saved as `textured_mesh.glb`.
+
+```bash
+python3 demo.py
+```
+**Optional arguments in `demo.py`:**
+
+- `max_num_view` : Maximum number of views, adaptively selected by the model (integer between 6 to 9)
+
+- `resolution` : Resolution for generated PBR textures (512 or 768)
+
+**Memory Recommendation:** For `max_num_view=6` and `resolution=512`, we recommend using a GPU with at least **21GB VRAM**.
+
+## Training
+
+### Data Prepare
+We provide a piece of data in `train_examples` for the overfitting training test. The data structure should be organized as follows:
+
+```
+train_examples/
+├── examples.json
+└── 001/
+ ├── render_tex/ # Rendered generated PBR images
+ │ ├── 000.png # Rendered views (RGB images)
+ │ ├── 000_albedo.png # Albedo maps for each view
+ │ ├── 000_mr.png # Metallic-Roughness maps for each view, R and G channels
+ │ ├── 000_normal.png # Normal maps
+ │ ├── 000_normal.png # Normal maps
+ │ ├── 000_pos.png # Position maps
+ │ ├── 000_pos.png # Position maps
+ │ ├── 001.png # Additional views...
+ │ ├── 001_albedo.png
+ │ ├── 001_mr.png
+ │ ├── 001_normal.png
+ │ ├── 001_pos.png
+ │ └── ... # More views (002, 003, 004, 005, ...)
+ └── render_cond/ # Rendered reference images (at least two light conditions should be rendered to facilitate consistency loss)
+ ├── 000_light_AL.png # Light condition 1 (Area Light)
+ ├── 000_light_ENVMAP.png # Light condition 2 (Environment map)
+ ├── 000_light_PL.png # Light condition 3 (Point lighting)
+ ├── 001_light_AL.png
+ ├── 001_light_ENVMAP.png
+ ├── 001_light_PL.png
+ └── ... # More lighting conditions (002-005, ...)
+```
+
+Each training example contains:
+- **render_tex/**: Multi-view renderings with PBR material properties
+ - Main RGB images (`XXX.png`)
+ - Albedo maps (`XXX_albedo.png`)
+ - Metallic-Roughness maps (`XXX_mr.png`)
+ - Normal maps (`XXX_normal.png/jpg`)
+ - Position maps (`XXX_pos.png/jpg`)
+ - Camera transforms (`transforms.json`)
+- **render_cond/**: Lighting condition maps for each view
+ - Ambient lighting (`XXX_light_AL.png`)
+ - Environment map lighting (`XXX_light_ENVMAP.png`)
+ - Point lighting (`XXX_light_PL.png`)
+
+### Launch Training
+
+
+```bash
+python3 train.py --base 'cfgs/hunyuan-paint-pbr.yaml' --name overfit --logdir logs/
+```
+
+## BibTeX
+
+If you found Hunyuan3D-Paint 2.1 helpful, please cite our papers:
+
+```bibtex
+@article{feng2025romantex,
+ title={RomanTex: Decoupling 3D-aware Rotary Positional Embedded Multi-Attention Network for Texture Synthesis},
+ author={Feng, Yifei and Yang, Mingxin and Yang, Shuhui and Zhang, Sheng and Yu, Jiaao and Zhao, Zibo and Liu, Yuhong and Jiang, Jie and Guo, Chunchao},
+ journal={arXiv preprint arXiv:2503.19011},
+ year={2025}
+}
+
+@article{he2025materialmvp,
+ title={MaterialMVP: Illumination-Invariant Material Generation via Multi-view PBR Diffusion},
+ author={He, Zebin and Yang, Mingxin and Yang, Shuhui and Tang, Yixuan and Wang, Tao and Zhang, Kaihao and Chen, Guanying and Liu, Yuhong and Jiang, Jie and Guo, Chunchao and Luo, Wenhan},
+ journal={arXiv preprint arXiv:2503.10289},
+ year={2025}
+}
+```
diff --git a/Hunyuan3D-2.1/hy3dpaint/assets/case_1/image.png b/Hunyuan3D-2.1/hy3dpaint/assets/case_1/image.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b55c4c2617ad346d4f0848364407a416abc45f1
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/assets/case_1/image.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3e29da7245fddb6ac4a571a6243c2e6256ccb753b094b7facdcbbcb018358c66
+size 883766
diff --git a/Hunyuan3D-2.1/hy3dpaint/assets/case_2/image.png b/Hunyuan3D-2.1/hy3dpaint/assets/case_2/image.png
new file mode 100644
index 0000000000000000000000000000000000000000..87f7c930db3836cda43434df77d8d4b103438826
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/assets/case_2/image.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7df0fab6bee93246d0609f36265ae1fb39008c3e76613ee54c501be899dab673
+size 663763
diff --git a/Hunyuan3D-2.1/hy3dpaint/cfgs/hunyuan-paint-pbr.yaml b/Hunyuan3D-2.1/hy3dpaint/cfgs/hunyuan-paint-pbr.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..27ed492e128832e2218d260265195b2a9b310d34
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/cfgs/hunyuan-paint-pbr.yaml
@@ -0,0 +1,52 @@
+model:
+ base_learning_rate: 5.0e-05
+ target: hunyuanpaintpbr.model.HunyuanPaint
+ params:
+ num_view: 6
+ view_size: 512
+ drop_cond_prob: 0.1
+
+ noise_in_channels: 12
+
+ stable_diffusion_config:
+ pretrained_model_name_or_path: stabilityai/stable-diffusion-2-1
+ custom_pipeline: ./hunyuanpaintpbr
+
+
+data:
+ target: src.data.objaverse_hunyuan.DataModuleFromConfig
+ params:
+ batch_size: 1
+ num_workers: 4
+ train:
+ -
+ target: src.data.dataloader.objaverse_loader_forTexturePBR.TextureDataset
+ params:
+ num_view: 6
+ json_path: train_examples/examples.json
+ validation:
+ -
+ target: src.data.dataloader.objaverse_loader_forTexturePBR.TextureDataset
+ params:
+ num_view: 6
+ json_path: train_examples/examples.json
+
+lightning:
+ modelcheckpoint:
+ params:
+ every_n_train_steps: 10000
+ save_top_k: -1
+ save_last: true
+ callbacks: {}
+
+ trainer:
+ benchmark: true
+ max_epochs: -1
+ gradient_clip_val: 1.0
+ val_check_interval: 1000
+ num_sanity_val_steps: 0
+ accumulate_grad_batches: 1
+ check_val_every_n_epoch: null # if not set this, validation does not run
+
+init_control_from:
+resume_from:
diff --git a/Hunyuan3D-2.1/hy3dpaint/convert_utils.py b/Hunyuan3D-2.1/hy3dpaint/convert_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ca66c0b5bae337417e40a0669a780ef94602097
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/convert_utils.py
@@ -0,0 +1,140 @@
+import trimesh
+import pygltflib
+import numpy as np
+from PIL import Image
+import base64
+import io
+
+
+def combine_metallic_roughness(metallic_path, roughness_path, output_path):
+ """
+ 将metallic和roughness贴图合并为一张贴图
+ GLB格式要求metallic在B通道,roughness在G通道
+ """
+ # 加载贴图
+ metallic_img = Image.open(metallic_path).convert("L") # 转为灰度
+ roughness_img = Image.open(roughness_path).convert("L") # 转为灰度
+
+ # 确保尺寸一致
+ if metallic_img.size != roughness_img.size:
+ roughness_img = roughness_img.resize(metallic_img.size)
+
+ # 创建RGB图像
+ width, height = metallic_img.size
+ combined = Image.new("RGB", (width, height))
+
+ # 转为numpy数组便于操作
+ metallic_array = np.array(metallic_img)
+ roughness_array = np.array(roughness_img)
+
+ # 创建合并的数组 (R, G, B) = (AO, Roughness, Metallic)
+ combined_array = np.zeros((height, width, 3), dtype=np.uint8)
+ combined_array[:, :, 0] = 255 # R通道:AO (如果没有AO贴图,设为白色)
+ combined_array[:, :, 1] = roughness_array # G通道:Roughness
+ combined_array[:, :, 2] = metallic_array # B通道:Metallic
+
+ # 转回PIL图像并保存
+ combined = Image.fromarray(combined_array)
+ combined.save(output_path)
+ return output_path
+
+
+def create_glb_with_pbr_materials(obj_path, textures_dict, output_path):
+ """
+ 使用pygltflib创建包含完整PBR材质的GLB文件
+
+ textures_dict = {
+ 'albedo': 'path/to/albedo.png',
+ 'metallic': 'path/to/metallic.png',
+ 'roughness': 'path/to/roughness.png',
+ 'normal': 'path/to/normal.png', # 可选
+ 'ao': 'path/to/ao.png' # 可选
+ }
+ """
+ # 1. 加载OBJ文件
+ mesh = trimesh.load(obj_path)
+
+ # 2. 先导出为临时GLB
+ temp_glb = "temp.glb"
+ mesh.export(temp_glb)
+
+ # 3. 加载GLB文件进行材质编辑
+ gltf = pygltflib.GLTF2().load(temp_glb)
+
+ # 4. 准备纹理数据
+ def image_to_data_uri(image_path):
+ """将图像转换为data URI"""
+ with open(image_path, "rb") as f:
+ image_data = f.read()
+ encoded = base64.b64encode(image_data).decode()
+ return f"data:image/png;base64,{encoded}"
+
+ # 5. 合并metallic和roughness
+ if "metallic" in textures_dict and "roughness" in textures_dict:
+ mr_combined_path = "mr_combined.png"
+ combine_metallic_roughness(textures_dict["metallic"], textures_dict["roughness"], mr_combined_path)
+ textures_dict["metallicRoughness"] = mr_combined_path
+
+ # 6. 添加图像到GLTF
+ images = []
+ textures = []
+
+ texture_mapping = {
+ "albedo": "baseColorTexture",
+ "metallicRoughness": "metallicRoughnessTexture",
+ "normal": "normalTexture",
+ "ao": "occlusionTexture",
+ }
+
+ for tex_type, tex_path in textures_dict.items():
+ if tex_type in texture_mapping and tex_path:
+ # 添加图像
+ image = pygltflib.Image(uri=image_to_data_uri(tex_path))
+ images.append(image)
+
+ # 添加纹理
+ texture = pygltflib.Texture(source=len(images) - 1)
+ textures.append(texture)
+
+ # 7. 创建PBR材质
+ pbr_metallic_roughness = pygltflib.PbrMetallicRoughness(
+ baseColorFactor=[1.0, 1.0, 1.0, 1.0], metallicFactor=1.0, roughnessFactor=1.0
+ )
+
+ # 设置纹理索引
+ texture_index = 0
+ if "albedo" in textures_dict:
+ pbr_metallic_roughness.baseColorTexture = pygltflib.TextureInfo(index=texture_index)
+ texture_index += 1
+
+ if "metallicRoughness" in textures_dict:
+ pbr_metallic_roughness.metallicRoughnessTexture = pygltflib.TextureInfo(index=texture_index)
+ texture_index += 1
+
+ # 创建材质
+ material = pygltflib.Material(name="PBR_Material", pbrMetallicRoughness=pbr_metallic_roughness)
+
+ # 添加法线贴图
+ if "normal" in textures_dict:
+ material.normalTexture = pygltflib.NormalTextureInfo(index=texture_index)
+ texture_index += 1
+
+ # 添加AO贴图
+ if "ao" in textures_dict:
+ material.occlusionTexture = pygltflib.OcclusionTextureInfo(index=texture_index)
+
+ # 8. 更新GLTF
+ gltf.images = images
+ gltf.textures = textures
+ gltf.materials = [material]
+
+ # 确保mesh使用材质
+ if gltf.meshes:
+ for primitive in gltf.meshes[0].primitives:
+ primitive.material = 0
+
+ # 9. 保存最终GLB
+ gltf.save(output_path)
+ print(f"PBR GLB文件已保存: {output_path}")
+
+
diff --git a/Hunyuan3D-2.1/hy3dpaint/demo.py b/Hunyuan3D-2.1/hy3dpaint/demo.py
new file mode 100644
index 0000000000000000000000000000000000000000..44fb296526dacb4d82b85ac1228c34c6e7f26e00
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/demo.py
@@ -0,0 +1,35 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from textureGenPipeline import Hunyuan3DPaintPipeline, Hunyuan3DPaintConfig
+
+try:
+ from utils.torchvision_fix import apply_fix
+
+ apply_fix()
+except ImportError:
+ print("Warning: torchvision_fix module not found, proceeding without compatibility fix")
+except Exception as e:
+ print(f"Warning: Failed to apply torchvision fix: {e}")
+
+
+if __name__ == "__main__":
+
+ max_num_view = 6 # can be 6 to 9
+ resolution = 512 # can be 768 or 512
+
+ conf = Hunyuan3DPaintConfig(max_num_view, resolution)
+ paint_pipeline = Hunyuan3DPaintPipeline(conf)
+ output_mesh_path = paint_pipeline(mesh_path="./assets/case_1/mesh.glb", image_path="./assets/case_1/image.png")
+ print(f"Output mesh path: {output_mesh_path}")
diff --git a/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/__init__.py b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..930d2fc856340ae4d9739925087304b4957f2c7f
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/__init__.py
@@ -0,0 +1,39 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from .pipeline import HunyuanPaintPipeline
+from .unet.model import HunyuanPaint
+from .unet.modules import (
+ Dino_v2,
+ Basic2p5DTransformerBlock,
+ ImageProjModel,
+ UNet2p5DConditionModel,
+)
+from .unet.attn_processor import (
+ PoseRoPEAttnProcessor2_0,
+ SelfAttnProcessor2_0,
+ RefAttnProcessor2_0,
+)
+
+__all__ = [
+ 'HunyuanPaintPipeline',
+ 'HunyuanPaint',
+ 'Dino_v2',
+ 'Basic2p5DTransformerBlock',
+ 'ImageProjModel',
+ 'UNet2p5DConditionModel',
+ 'PoseRoPEAttnProcessor2_0',
+ 'SelfAttnProcessor2_0',
+ 'RefAttnProcessor2_0',
+]
diff --git a/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/pipeline.py b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/pipeline.py
new file mode 100644
index 0000000000000000000000000000000000000000..871dae58e968cf887529a25b8d6fb48da5a97b4b
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/pipeline.py
@@ -0,0 +1,736 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from typing import Any, Dict, Optional
+from diffusers.models import AutoencoderKL, UNet2DConditionModel
+from diffusers.schedulers import KarrasDiffusionSchedulers
+
+import numpy
+import torch
+import torch.utils.checkpoint
+import torch.distributed
+import numpy as np
+import transformers
+from PIL import Image
+from einops import rearrange
+from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer, CLIPVisionModelWithProjection
+from typing import Any, Callable, Dict, List, Optional, Union, Tuple
+
+import diffusers
+from diffusers import (
+ AutoencoderKL,
+ DiffusionPipeline,
+ UNet2DConditionModel,
+)
+from diffusers.image_processor import VaeImageProcessor
+
+from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import (
+ StableDiffusionPipeline,
+ retrieve_timesteps,
+ rescale_noise_cfg,
+)
+
+from diffusers.utils import deprecate
+from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback
+from diffusers.image_processor import PipelineImageInput
+from diffusers.pipelines.stable_diffusion.pipeline_output import StableDiffusionPipelineOutput
+from .unet.modules import UNet2p5DConditionModel
+from .unet.attn_processor import SelfAttnProcessor2_0, RefAttnProcessor2_0, PoseRoPEAttnProcessor2_0
+
+__all__ = [
+ "HunyuanPaintPipeline",
+ "UNet2p5DConditionModel",
+ "SelfAttnProcessor2_0",
+ "RefAttnProcessor2_0",
+ "PoseRoPEAttnProcessor2_0",
+]
+
+
+def to_rgb_image(maybe_rgba: Image.Image):
+ if maybe_rgba.mode == "RGB":
+ return maybe_rgba
+ elif maybe_rgba.mode == "RGBA":
+ rgba = maybe_rgba
+ img = numpy.random.randint(127, 128, size=[rgba.size[1], rgba.size[0], 3], dtype=numpy.uint8)
+ img = Image.fromarray(img, "RGB")
+ img.paste(rgba, mask=rgba.getchannel("A"))
+ return img
+ else:
+ raise ValueError("Unsupported image type.", maybe_rgba.mode)
+
+
+class HunyuanPaintPipeline(StableDiffusionPipeline):
+
+ """Custom pipeline for multiview PBR texture generation.
+
+ Extends Stable Diffusion with:
+ - Material-specific conditioning
+ - Multiview processing
+ - Position-aware attention
+ - 2.5D UNet integration
+ """
+
+ def __init__(
+ self,
+ vae: AutoencoderKL,
+ text_encoder: CLIPTextModel,
+ tokenizer: CLIPTokenizer,
+ unet: UNet2DConditionModel,
+ scheduler: KarrasDiffusionSchedulers,
+ feature_extractor: CLIPImageProcessor,
+ safety_checker=None,
+ use_torch_compile=False,
+ ):
+ DiffusionPipeline.__init__(self)
+
+ safety_checker = None
+ self.register_modules(
+ vae=torch.compile(vae) if use_torch_compile else vae,
+ text_encoder=text_encoder,
+ tokenizer=tokenizer,
+ unet=unet,
+ scheduler=scheduler,
+ safety_checker=safety_checker,
+ feature_extractor=torch.compile(feature_extractor) if use_torch_compile else feature_extractor,
+ )
+
+ self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
+ self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor)
+
+ if isinstance(self.unet, UNet2DConditionModel):
+ self.unet = UNet2p5DConditionModel(self.unet, None, self.scheduler)
+
+ def eval(self):
+ self.unet.eval()
+ self.vae.eval()
+
+ def set_pbr_settings(self, pbr_settings: List[str]):
+ self.pbr_settings = pbr_settings
+
+ def set_learned_parameters(self):
+
+ """Configures parameter freezing strategy.
+
+ Freezes:
+ - Standard attention layers
+ - Dual-stream reference UNet
+
+ Unfreezes:
+ - Material-specific parameters
+ - DINO integration components
+ """
+
+ freezed_names = ["attn1", "unet_dual"]
+ added_learned_names = ["albedo", "mr", "dino"]
+
+ for name, params in self.unet.named_parameters():
+ if any(freeze_name in name for freeze_name in freezed_names) and all(
+ learned_name not in name for learned_name in added_learned_names
+ ):
+ params.requires_grad = False
+ else:
+ params.requires_grad = True
+
+ def prepare(self):
+ if isinstance(self.unet, UNet2DConditionModel):
+ self.unet = UNet2p5DConditionModel(self.unet, None, self.scheduler).eval()
+
+ @torch.no_grad()
+ def encode_images(self, images):
+
+ """Encodes multiview image batches into latent space.
+
+ Args:
+ images: Input images [B, N_views, C, H, W]
+
+ Returns:
+ torch.Tensor: Latent representations [B, N_views, C, H_latent, W_latent]
+ """
+
+ B = images.shape[0]
+ images = rearrange(images, "b n c h w -> (b n) c h w")
+
+ dtype = next(self.vae.parameters()).dtype
+ images = (images - 0.5) * 2.0
+ posterior = self.vae.encode(images.to(dtype)).latent_dist
+ latents = posterior.sample() * self.vae.config.scaling_factor
+
+ latents = rearrange(latents, "(b n) c h w -> b n c h w", b=B)
+ return latents
+
+ @torch.no_grad()
+ def __call__(
+ self,
+ images=None,
+ prompt=None,
+ negative_prompt="watermark, ugly, deformed, noisy, blurry, low contrast",
+ *args,
+ num_images_per_prompt: Optional[int] = 1,
+ guidance_scale=3.0,
+ output_type: Optional[str] = "pil",
+ width=512,
+ height=512,
+ num_inference_steps=15,
+ return_dict=True,
+ sync_condition=None,
+ **cached_condition,
+ ):
+
+ """Main generation method for multiview PBR textures.
+
+ Steps:
+ 1. Input validation and preparation
+ 2. Reference image encoding
+ 3. Condition processing (normal/position maps)
+ 4. Prompt embedding setup
+ 5. Classifier-free guidance preparation
+ 6. Diffusion sampling loop
+
+ Args:
+ images: List of reference PIL images
+ prompt: Text prompt (overridden by learned embeddings)
+ cached_condition: Dictionary containing:
+ - images_normal: Normal maps (PIL or tensor)
+ - images_position: Position maps (PIL or tensor)
+
+ Returns:
+ List[PIL.Image]: Generated multiview PBR textures
+ """
+
+ self.prepare()
+ if images is None:
+ raise ValueError("Inputting embeddings not supported for this pipeline. Please pass an image.")
+ assert not isinstance(images, torch.Tensor)
+
+ if not isinstance(images, List):
+ images = [images]
+
+ images = [to_rgb_image(image) for image in images]
+ images_vae = [torch.tensor(np.array(image) / 255.0) for image in images]
+ images_vae = [image_vae.unsqueeze(0).permute(0, 3, 1, 2).unsqueeze(0) for image_vae in images_vae]
+ images_vae = torch.cat(images_vae, dim=1)
+ images_vae = images_vae.to(device=self.vae.device, dtype=self.unet.dtype)
+
+ batch_size = images_vae.shape[0]
+ N_ref = images_vae.shape[1]
+
+ assert batch_size == 1
+ assert num_images_per_prompt == 1
+
+ if self.unet.use_ra:
+ ref_latents = self.encode_images(images_vae)
+ cached_condition["ref_latents"] = ref_latents
+
+ def convert_pil_list_to_tensor(images):
+ bg_c = [1.0, 1.0, 1.0]
+ images_tensor = []
+ for batch_imgs in images:
+ view_imgs = []
+ for pil_img in batch_imgs:
+ img = numpy.asarray(pil_img, dtype=numpy.float32) / 255.0
+ if img.shape[2] > 3:
+ alpha = img[:, :, 3:]
+ img = img[:, :, :3] * alpha + bg_c * (1 - alpha)
+ img = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0).contiguous().half().to("cuda")
+ view_imgs.append(img)
+ view_imgs = torch.cat(view_imgs, dim=0)
+ images_tensor.append(view_imgs.unsqueeze(0))
+
+ images_tensor = torch.cat(images_tensor, dim=0)
+ return images_tensor
+
+ if "images_normal" in cached_condition:
+ if isinstance(cached_condition["images_normal"], List):
+ cached_condition["images_normal"] = convert_pil_list_to_tensor(cached_condition["images_normal"])
+
+ cached_condition["embeds_normal"] = self.encode_images(cached_condition["images_normal"])
+
+ if "images_position" in cached_condition:
+
+ if isinstance(cached_condition["images_position"], List):
+ cached_condition["images_position"] = convert_pil_list_to_tensor(cached_condition["images_position"])
+
+ cached_condition["position_maps"] = cached_condition["images_position"]
+ cached_condition["embeds_position"] = self.encode_images(cached_condition["images_position"])
+
+ if self.unet.use_learned_text_clip:
+
+ all_shading_tokens = []
+ for token in self.unet.pbr_setting:
+ all_shading_tokens.append(
+ getattr(self.unet, f"learned_text_clip_{token}").unsqueeze(dim=0).repeat(batch_size, 1, 1)
+ )
+ prompt_embeds = torch.stack(all_shading_tokens, dim=1)
+ negative_prompt_embeds = torch.stack(all_shading_tokens, dim=1)
+ # negative_prompt_embeds = torch.zeros_like(prompt_embeds)
+
+ else:
+ if prompt is None:
+ prompt = "high quality"
+ if isinstance(prompt, str):
+ prompt = [prompt for _ in range(batch_size)]
+ device = self._execution_device
+ prompt_embeds, _ = self.encode_prompt(
+ prompt, device=device, num_images_per_prompt=num_images_per_prompt, do_classifier_free_guidance=False
+ )
+
+ if isinstance(negative_prompt, str):
+ negative_prompt = [negative_prompt for _ in range(batch_size)]
+ if negative_prompt is not None:
+ negative_prompt_embeds, _ = self.encode_prompt(
+ negative_prompt,
+ device=device,
+ num_images_per_prompt=num_images_per_prompt,
+ do_classifier_free_guidance=False,
+ )
+ else:
+ negative_prompt_embeds = torch.zeros_like(prompt_embeds)
+
+ if guidance_scale > 1:
+ if self.unet.use_ra:
+ cached_condition["ref_latents"] = cached_condition["ref_latents"].repeat(
+ 3, *([1] * (cached_condition["ref_latents"].dim() - 1))
+ )
+ cached_condition["ref_scale"] = torch.as_tensor([0.0, 1.0, 1.0]).to(cached_condition["ref_latents"])
+
+ if self.unet.use_dino:
+ zero_states = torch.zeros_like(cached_condition["dino_hidden_states"])
+ cached_condition["dino_hidden_states"] = torch.cat(
+ [zero_states, zero_states, cached_condition["dino_hidden_states"]]
+ )
+
+ del zero_states
+ if "embeds_normal" in cached_condition:
+ cached_condition["embeds_normal"] = cached_condition["embeds_normal"].repeat(
+ 3, *([1] * (cached_condition["embeds_normal"].dim() - 1))
+ )
+
+ if "embeds_position" in cached_condition:
+ cached_condition["embeds_position"] = cached_condition["embeds_position"].repeat(
+ 3, *([1] * (cached_condition["embeds_position"].dim() - 1))
+ )
+
+ if "position_maps" in cached_condition:
+ cached_condition["position_maps"] = cached_condition["position_maps"].repeat(
+ 3, *([1] * (cached_condition["position_maps"].dim() - 1))
+ )
+
+ images = self.denoise(
+ None,
+ *args,
+ cross_attention_kwargs=None,
+ guidance_scale=guidance_scale,
+ num_images_per_prompt=num_images_per_prompt,
+ prompt_embeds=prompt_embeds,
+ negative_prompt_embeds=negative_prompt_embeds,
+ num_inference_steps=num_inference_steps,
+ output_type=output_type,
+ width=width,
+ height=height,
+ return_dict=return_dict,
+ **cached_condition,
+ )
+
+ return images
+
+ def denoise(
+ self,
+ prompt: Union[str, List[str]] = None,
+ height: Optional[int] = None,
+ width: Optional[int] = None,
+ num_inference_steps: int = 50,
+ timesteps: List[int] = None,
+ sigmas: List[float] = None,
+ guidance_scale: float = 7.5,
+ negative_prompt: Optional[Union[str, List[str]]] = None,
+ num_images_per_prompt: Optional[int] = 1,
+ eta: float = 0.0,
+ generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
+ latents: Optional[torch.Tensor] = None,
+ prompt_embeds: Optional[torch.Tensor] = None,
+ negative_prompt_embeds: Optional[torch.Tensor] = None,
+ ip_adapter_image: Optional[PipelineImageInput] = None,
+ ip_adapter_image_embeds: Optional[List[torch.Tensor]] = None,
+ output_type: Optional[str] = "pil",
+ return_dict: bool = True,
+ cross_attention_kwargs: Optional[Dict[str, Any]] = None,
+ guidance_rescale: float = 0.0,
+ clip_skip: Optional[int] = None,
+ callback_on_step_end: Optional[
+ Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks]
+ ] = None,
+ callback_on_step_end_tensor_inputs: List[str] = ["latents"],
+ **kwargs,
+ ):
+ r"""
+ The call function to the pipeline for generation.
+
+ Args:
+ prompt (`str` or `List[str]`, *optional*):
+ The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`.
+ height (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
+ The height in pixels of the generated image.
+ width (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
+ The width in pixels of the generated image.
+ num_inference_steps (`int`, *optional*, defaults to 50):
+ The number of denoising steps. More denoising steps usually lead to a higher quality image at the
+ expense of slower inference.
+ timesteps (`List[int]`, *optional*):
+ Custom timesteps to use for the denoising process with schedulers which support a `timesteps` argument
+ in their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is
+ passed will be used. Must be in descending order.
+ sigmas (`List[float]`, *optional*):
+ Custom sigmas to use for the denoising process with schedulers which support a `sigmas` argument in
+ their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is passed
+ will be used.
+ guidance_scale (`float`, *optional*, defaults to 7.5):
+ A higher guidance scale value encourages the model to generate images closely linked to the text
+ `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.
+ negative_prompt (`str` or `List[str]`, *optional*):
+ The prompt or prompts to guide what to not include in image generation. If not defined, you need to
+ pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`).
+ num_images_per_prompt (`int`, *optional*, defaults to 1):
+ The number of images to generate per prompt.
+ eta (`float`, *optional*, defaults to 0.0):
+ Corresponds to parameter eta (η) from the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies
+ to the [`~schedulers.DDIMScheduler`], and is ignored in other schedulers.
+ generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
+ A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
+ generation deterministic.
+ latents (`torch.Tensor`, *optional*):
+ Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
+ generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
+ tensor is generated by sampling using the supplied random `generator`.
+ prompt_embeds (`torch.Tensor`, *optional*):
+ Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
+ provided, text embeddings are generated from the `prompt` input argument.
+ negative_prompt_embeds (`torch.Tensor`, *optional*):
+ Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If
+ not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument.
+ ip_adapter_image: (`PipelineImageInput`, *optional*): Optional image input to work with IP Adapters.
+ ip_adapter_image_embeds (`List[torch.Tensor]`, *optional*):
+ Pre-generated image embeddings for IP-Adapter. It should be a list of length same as number of
+ IP-adapters. Each element should be a tensor of shape `(batch_size, num_images, emb_dim)`. It should
+ contain the negative image embedding if `do_classifier_free_guidance` is set to `True`. If not
+ provided, embeddings are computed from the `ip_adapter_image` input argument.
+ output_type (`str`, *optional*, defaults to `"pil"`):
+ The output format of the generated image. Choose between `PIL.Image` or `np.array`.
+ return_dict (`bool`, *optional*, defaults to `True`):
+ Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a
+ plain tuple.
+ cross_attention_kwargs (`dict`, *optional*):
+ A kwargs dictionary that if specified is passed along to the [`AttentionProcessor`] as defined in
+ [`self.processor`]
+ (https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
+ guidance_rescale (`float`, *optional*, defaults to 0.0):
+ Guidance rescale factor from [Common Diffusion Noise Schedules and Sample Steps are
+ Flawed](https://arxiv.org/pdf/2305.08891.pdf). Guidance rescale factor should fix overexposure when
+ using zero terminal SNR.
+ clip_skip (`int`, *optional*):
+ Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
+ the output of the pre-final layer will be used for computing the prompt embeddings.
+ callback_on_step_end (`Callable`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*):
+ A function or a subclass of `PipelineCallback` or `MultiPipelineCallbacks` that is called at the end of
+ each denoising step during the inference. with the following arguments: `callback_on_step_end(self:
+ DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)`. `callback_kwargs` will include a
+ list of all tensors as specified by `callback_on_step_end_tensor_inputs`.
+ callback_on_step_end_tensor_inputs (`List`, *optional*):
+ The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
+ will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
+ `._callback_tensor_inputs` attribute of your pipeline class.
+
+ Examples:
+
+ Returns:
+ [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:
+ If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned,
+ otherwise a `tuple` is returned where the first element is a list with the generated images and the
+ second element is a list of `bool`s indicating whether the corresponding generated image contains
+ "not-safe-for-work" (nsfw) content.
+
+ Core denoising procedure for multiview PBR texture generation.
+
+ Handles the complete diffusion process including:
+ - Input validation and preparation
+ - Timestep scheduling
+ - Latent noise initialization
+ - Iterative denoising with specialized guidance
+ - Output decoding and post-processing
+
+ Key innovations:
+ 1. Triple-batch classifier-free guidance:
+ - Negative (unconditional)
+ - Reference-conditioned
+ - Full-conditioned
+ 2. View-dependent guidance scaling:
+ - Adjusts influence based on camera azimuth
+ 3. PBR-aware latent organization:
+ - Maintains material/view separation throughout
+ 4. Optimized VRAM management:
+ - Selective tensor reshaping
+
+ Processing Stages:
+ 1. Setup & Validation: Configures pipeline components and validates inputs
+ 2. Prompt Encoding: Processes text/material conditioning
+ 3. Latent Initialization: Prepares noise for denoising process
+ 4. Iterative Denoising:
+ a) Scales and organizes latent variables
+ b) Predicts noise at current timestep
+ c) Applies view-dependent guidance
+ d) Computes previous latent state
+ 5. Output Decoding: Converts latents to final images
+ 6. Cleanup: Releases resources and formats output
+
+ """
+
+ callback = kwargs.pop("callback", None)
+ callback_steps = kwargs.pop("callback_steps", None)
+
+ # open cache
+ kwargs["cache"] = {}
+
+ if callback is not None:
+ deprecate(
+ "callback",
+ "1.0.0",
+ "Passing `callback` as an input argument to `__call__` is deprecated,"
+ "consider using `callback_on_step_end`",
+ )
+ if callback_steps is not None:
+ deprecate(
+ "callback_steps",
+ "1.0.0",
+ "Passing `callback` as an input argument to `__call__` is deprecated,"
+ "consider using `callback_on_step_end`",
+ )
+
+ if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)):
+ callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs
+
+ # 0. Default height and width to unet
+ height = height or self.unet.config.sample_size * self.vae_scale_factor
+ width = width or self.unet.config.sample_size * self.vae_scale_factor
+ # to deal with lora scaling and other possible forward hooks
+
+ # 1. Check inputs. Raise error if not correct
+ self.check_inputs(
+ prompt,
+ height,
+ width,
+ callback_steps,
+ negative_prompt,
+ prompt_embeds,
+ negative_prompt_embeds,
+ ip_adapter_image,
+ ip_adapter_image_embeds,
+ callback_on_step_end_tensor_inputs,
+ )
+
+ self._guidance_scale = guidance_scale
+ self._guidance_rescale = guidance_rescale
+ self._clip_skip = clip_skip
+ self._cross_attention_kwargs = cross_attention_kwargs
+ self._interrupt = False
+
+ # 2. Define call parameters
+ if prompt is not None and isinstance(prompt, str):
+ batch_size = 1
+ elif prompt is not None and isinstance(prompt, list):
+ batch_size = len(prompt)
+ else:
+ batch_size = prompt_embeds.shape[0]
+
+ device = self._execution_device
+
+ # 3. Encode input prompt
+ lora_scale = self.cross_attention_kwargs.get("scale", None) if self.cross_attention_kwargs is not None else None
+
+ """
+ prompt_embeds, negative_prompt_embeds = self.encode_prompt(
+ prompt,
+ device,
+ num_images_per_prompt,
+ self.do_classifier_free_guidance,
+ negative_prompt,
+ prompt_embeds=prompt_embeds,
+ negative_prompt_embeds=negative_prompt_embeds,
+ lora_scale=lora_scale,
+ clip_skip=self.clip_skip,
+ )'
+ """
+
+ # For classifier free guidance, we need to do two forward passes.
+ # Here we concatenate the unconditional and text embeddings into a single batch
+ # to avoid doing two forward passes
+ if self.do_classifier_free_guidance:
+ # prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
+ prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds, prompt_embeds])
+
+ if ip_adapter_image is not None or ip_adapter_image_embeds is not None:
+ image_embeds = self.prepare_ip_adapter_image_embeds(
+ ip_adapter_image,
+ ip_adapter_image_embeds,
+ device,
+ batch_size * num_images_per_prompt,
+ self.do_classifier_free_guidance,
+ )
+
+ # 4. Prepare timesteps
+ timesteps, num_inference_steps = retrieve_timesteps(
+ self.scheduler, num_inference_steps, device, timesteps, sigmas
+ )
+ assert num_images_per_prompt == 1
+ # 5. Prepare latent variables
+ n_pbr = len(self.unet.pbr_setting)
+ num_channels_latents = self.unet.config.in_channels
+ latents = self.prepare_latents(
+ batch_size * kwargs["num_in_batch"] * n_pbr, # num_images_per_prompt,
+ num_channels_latents,
+ height,
+ width,
+ prompt_embeds.dtype,
+ device,
+ generator,
+ latents,
+ )
+
+ # 6. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
+
+ # 6.1 Add image embeds for IP-Adapter
+ added_cond_kwargs = (
+ {"image_embeds": image_embeds}
+ if (ip_adapter_image is not None or ip_adapter_image_embeds is not None)
+ else None
+ )
+
+ # 6.2 Optionally get Guidance Scale Embedding
+ timestep_cond = None
+ if self.unet.config.time_cond_proj_dim is not None:
+ guidance_scale_tensor = torch.tensor(self.guidance_scale - 1).repeat(batch_size * num_images_per_prompt)
+ timestep_cond = self.get_guidance_scale_embedding(
+ guidance_scale_tensor, embedding_dim=self.unet.config.time_cond_proj_dim
+ ).to(device=device, dtype=latents.dtype)
+
+ # 7. Denoising loop
+ num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
+ self._num_timesteps = len(timesteps)
+ with self.progress_bar(total=num_inference_steps) as progress_bar:
+ for i, t in enumerate(timesteps):
+ if self.interrupt:
+ continue
+
+ # expand the latents if we are doing classifier free guidance
+ latents = rearrange(
+ latents, "(b n_pbr n) c h w -> b n_pbr n c h w", n=kwargs["num_in_batch"], n_pbr=n_pbr
+ )
+ # latent_model_input = torch.cat([latents] * 3) if self.do_classifier_free_guidance else latents
+ latent_model_input = latents.repeat(3, 1, 1, 1, 1, 1) if self.do_classifier_free_guidance else latents
+ latent_model_input = rearrange(latent_model_input, "b n_pbr n c h w -> (b n_pbr n) c h w")
+ latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
+ latent_model_input = rearrange(
+ latent_model_input, "(b n_pbr n) c h w ->b n_pbr n c h w", n=kwargs["num_in_batch"], n_pbr=n_pbr
+ )
+
+ # predict the noise residual
+
+ noise_pred = self.unet(
+ latent_model_input,
+ t,
+ encoder_hidden_states=prompt_embeds,
+ timestep_cond=timestep_cond,
+ cross_attention_kwargs=self.cross_attention_kwargs,
+ added_cond_kwargs=added_cond_kwargs,
+ return_dict=False,
+ **kwargs,
+ )[0]
+ latents = rearrange(latents, "b n_pbr n c h w -> (b n_pbr n) c h w")
+ # perform guidance
+ if self.do_classifier_free_guidance:
+ # noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
+ # noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond)
+ noise_pred_uncond, noise_pred_ref, noise_pred_full = noise_pred.chunk(3)
+
+ if "camera_azims" in kwargs.keys():
+ camera_azims = kwargs["camera_azims"]
+ else:
+ camera_azims = [0] * kwargs["num_in_batch"]
+
+ def cam_mapping(azim):
+ if azim < 90 and azim >= 0:
+ return float(azim) / 90.0 + 1
+ elif azim >= 90 and azim < 330:
+ return 2.0
+ else:
+ return -float(azim) / 90.0 + 5.0
+
+ view_scale_tensor = (
+ torch.from_numpy(np.asarray([cam_mapping(azim) for azim in camera_azims]))
+ .unsqueeze(0)
+ .repeat(n_pbr, 1)
+ .view(-1)
+ .to(noise_pred_uncond)[:, None, None, None]
+ )
+ noise_pred = noise_pred_uncond + self.guidance_scale * view_scale_tensor * (
+ noise_pred_ref - noise_pred_uncond
+ )
+ noise_pred += self.guidance_scale * view_scale_tensor * (noise_pred_full - noise_pred_ref)
+
+ if self.do_classifier_free_guidance and self.guidance_rescale > 0.0:
+ # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf
+ noise_pred = rescale_noise_cfg(noise_pred, noise_pred_ref, guidance_rescale=self.guidance_rescale)
+
+ # compute the previous noisy sample x_t -> x_t-1
+ latents = self.scheduler.step(
+ noise_pred, t, latents[:, :num_channels_latents, :, :], **extra_step_kwargs, return_dict=False
+ )[0]
+
+ if callback_on_step_end is not None:
+ callback_kwargs = {}
+ for k in callback_on_step_end_tensor_inputs:
+ callback_kwargs[k] = locals()[k]
+ callback_outputs = callback_on_step_end(self, i, t, callback_kwargs)
+
+ latents = callback_outputs.pop("latents", latents)
+ prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds)
+ negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds)
+
+ # call the callback, if provided
+ if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
+ progress_bar.update()
+ if callback is not None and i % callback_steps == 0:
+ step_idx = i // getattr(self.scheduler, "order", 1)
+ callback(step_idx, t, latents)
+
+ if not output_type == "latent":
+ image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False, generator=generator)[0]
+ image, has_nsfw_concept = self.run_safety_checker(image, device, prompt_embeds.dtype)
+ else:
+ image = latents
+ has_nsfw_concept = None
+
+ if has_nsfw_concept is None:
+ do_denormalize = [True] * image.shape[0]
+ else:
+ do_denormalize = [not has_nsfw for has_nsfw in has_nsfw_concept]
+
+ image = self.image_processor.postprocess(image, output_type=output_type, do_denormalize=do_denormalize)
+
+ # Offload all models
+ self.maybe_free_model_hooks()
+
+ if not return_dict:
+ return (image, has_nsfw_concept)
+
+ return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept)
diff --git a/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/attn_processor.py b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/attn_processor.py
new file mode 100644
index 0000000000000000000000000000000000000000..37ebde0f6f30230351f757e050e3b86fd8a06402
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/attn_processor.py
@@ -0,0 +1,839 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from typing import Optional, Dict, Tuple, Union, Literal, List, Callable
+from einops import rearrange
+from diffusers.utils import deprecate
+from diffusers.models.attention_processor import Attention, AttnProcessor
+
+
+class AttnUtils:
+ """
+ Shared utility functions for attention processing.
+
+ This class provides common operations used across different attention processors
+ to eliminate code duplication and improve maintainability.
+ """
+
+ @staticmethod
+ def check_pytorch_compatibility():
+ """
+ Check PyTorch compatibility for scaled_dot_product_attention.
+
+ Raises:
+ ImportError: If PyTorch version doesn't support scaled_dot_product_attention
+ """
+ if not hasattr(F, "scaled_dot_product_attention"):
+ raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
+
+ @staticmethod
+ def handle_deprecation_warning(args, kwargs):
+ """
+ Handle deprecation warning for the 'scale' argument.
+
+ Args:
+ args: Positional arguments passed to attention processor
+ kwargs: Keyword arguments passed to attention processor
+ """
+ if len(args) > 0 or kwargs.get("scale", None) is not None:
+ deprecation_message = (
+ "The `scale` argument is deprecated and will be ignored."
+ "Please remove it, as passing it will raise an error in the future."
+ "`scale` should directly be passed while calling the underlying pipeline component"
+ "i.e., via `cross_attention_kwargs`."
+ )
+ deprecate("scale", "1.0.0", deprecation_message)
+
+ @staticmethod
+ def prepare_hidden_states(
+ hidden_states, attn, temb, spatial_norm_attr="spatial_norm", group_norm_attr="group_norm"
+ ):
+ """
+ Common preprocessing of hidden states for attention computation.
+
+ Args:
+ hidden_states: Input hidden states tensor
+ attn: Attention module instance
+ temb: Optional temporal embedding tensor
+ spatial_norm_attr: Attribute name for spatial normalization
+ group_norm_attr: Attribute name for group normalization
+
+ Returns:
+ Tuple of (processed_hidden_states, residual, input_ndim, shape_info)
+ """
+ residual = hidden_states
+
+ spatial_norm = getattr(attn, spatial_norm_attr, None)
+ if spatial_norm is not None:
+ hidden_states = spatial_norm(hidden_states, temb)
+
+ input_ndim = hidden_states.ndim
+
+ if input_ndim == 4:
+ batch_size, channel, height, width = hidden_states.shape
+ hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
+ else:
+ batch_size, channel, height, width = None, None, None, None
+
+ group_norm = getattr(attn, group_norm_attr, None)
+ if group_norm is not None:
+ hidden_states = group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
+
+ return hidden_states, residual, input_ndim, (batch_size, channel, height, width)
+
+ @staticmethod
+ def prepare_attention_mask(attention_mask, attn, sequence_length, batch_size):
+ """
+ Prepare attention mask for scaled_dot_product_attention.
+
+ Args:
+ attention_mask: Input attention mask tensor or None
+ attn: Attention module instance
+ sequence_length: Length of the sequence
+ batch_size: Batch size
+
+ Returns:
+ Prepared attention mask tensor reshaped for multi-head attention
+ """
+ if attention_mask is not None:
+ attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
+ attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
+ return attention_mask
+
+ @staticmethod
+ def reshape_qkv_for_attention(tensor, batch_size, attn_heads, head_dim):
+ """
+ Reshape Q/K/V tensors for multi-head attention computation.
+
+ Args:
+ tensor: Input tensor to reshape
+ batch_size: Batch size
+ attn_heads: Number of attention heads
+ head_dim: Dimension per attention head
+
+ Returns:
+ Reshaped tensor with shape [batch_size, attn_heads, seq_len, head_dim]
+ """
+ return tensor.view(batch_size, -1, attn_heads, head_dim).transpose(1, 2)
+
+ @staticmethod
+ def apply_norms(query, key, norm_q, norm_k):
+ """
+ Apply Q/K normalization layers if available.
+
+ Args:
+ query: Query tensor
+ key: Key tensor
+ norm_q: Query normalization layer (optional)
+ norm_k: Key normalization layer (optional)
+
+ Returns:
+ Tuple of (normalized_query, normalized_key)
+ """
+ if norm_q is not None:
+ query = norm_q(query)
+ if norm_k is not None:
+ key = norm_k(key)
+ return query, key
+
+ @staticmethod
+ def finalize_output(hidden_states, input_ndim, shape_info, attn, residual, to_out):
+ """
+ Common output processing including projection, dropout, reshaping, and residual connection.
+
+ Args:
+ hidden_states: Processed hidden states from attention
+ input_ndim: Original input tensor dimensions
+ shape_info: Tuple containing original shape information
+ attn: Attention module instance
+ residual: Residual connection tensor
+ to_out: Output projection layers [linear, dropout]
+
+ Returns:
+ Final output tensor after all processing steps
+ """
+ batch_size, channel, height, width = shape_info
+
+ # Apply output projection and dropout
+ hidden_states = to_out[0](hidden_states)
+ hidden_states = to_out[1](hidden_states)
+
+ # Reshape back if needed
+ if input_ndim == 4:
+ hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
+
+ # Apply residual connection
+ if attn.residual_connection:
+ hidden_states = hidden_states + residual
+
+ # Apply rescaling
+ hidden_states = hidden_states / attn.rescale_output_factor
+ return hidden_states
+
+
+# Base class for attention processors (eliminating initialization duplication)
+class BaseAttnProcessor(nn.Module):
+ """
+ Base class for attention processors with common initialization.
+
+ This base class provides shared parameter initialization and module registration
+ functionality to reduce code duplication across different attention processor types.
+ """
+
+ def __init__(
+ self,
+ query_dim: int,
+ pbr_setting: List[str] = ["albedo", "mr"],
+ cross_attention_dim: Optional[int] = None,
+ heads: int = 8,
+ kv_heads: Optional[int] = None,
+ dim_head: int = 64,
+ dropout: float = 0.0,
+ bias: bool = False,
+ upcast_attention: bool = False,
+ upcast_softmax: bool = False,
+ cross_attention_norm: Optional[str] = None,
+ cross_attention_norm_num_groups: int = 32,
+ qk_norm: Optional[str] = None,
+ added_kv_proj_dim: Optional[int] = None,
+ added_proj_bias: Optional[bool] = True,
+ norm_num_groups: Optional[int] = None,
+ spatial_norm_dim: Optional[int] = None,
+ out_bias: bool = True,
+ scale_qk: bool = True,
+ only_cross_attention: bool = False,
+ eps: float = 1e-5,
+ rescale_output_factor: float = 1.0,
+ residual_connection: bool = False,
+ _from_deprecated_attn_block: bool = False,
+ processor: Optional["AttnProcessor"] = None,
+ out_dim: int = None,
+ out_context_dim: int = None,
+ context_pre_only=None,
+ pre_only=False,
+ elementwise_affine: bool = True,
+ is_causal: bool = False,
+ **kwargs,
+ ):
+ """
+ Initialize base attention processor with common parameters.
+
+ Args:
+ query_dim: Dimension of query features
+ pbr_setting: List of PBR material types to process (e.g., ["albedo", "mr"])
+ cross_attention_dim: Dimension of cross-attention features (optional)
+ heads: Number of attention heads
+ kv_heads: Number of key-value heads for grouped query attention (optional)
+ dim_head: Dimension per attention head
+ dropout: Dropout rate
+ bias: Whether to use bias in linear projections
+ upcast_attention: Whether to upcast attention computation to float32
+ upcast_softmax: Whether to upcast softmax computation to float32
+ cross_attention_norm: Type of cross-attention normalization (optional)
+ cross_attention_norm_num_groups: Number of groups for cross-attention norm
+ qk_norm: Type of query-key normalization (optional)
+ added_kv_proj_dim: Dimension for additional key-value projections (optional)
+ added_proj_bias: Whether to use bias in additional projections
+ norm_num_groups: Number of groups for normalization (optional)
+ spatial_norm_dim: Dimension for spatial normalization (optional)
+ out_bias: Whether to use bias in output projection
+ scale_qk: Whether to scale query-key products
+ only_cross_attention: Whether to only perform cross-attention
+ eps: Small epsilon value for numerical stability
+ rescale_output_factor: Factor to rescale output values
+ residual_connection: Whether to use residual connections
+ _from_deprecated_attn_block: Flag for deprecated attention blocks
+ processor: Optional attention processor instance
+ out_dim: Output dimension (optional)
+ out_context_dim: Output context dimension (optional)
+ context_pre_only: Whether to only process context in pre-processing
+ pre_only: Whether to only perform pre-processing
+ elementwise_affine: Whether to use element-wise affine transformations
+ is_causal: Whether to use causal attention masking
+ **kwargs: Additional keyword arguments
+ """
+ super().__init__()
+ AttnUtils.check_pytorch_compatibility()
+
+ # Store common attributes
+ self.pbr_setting = pbr_setting
+ self.n_pbr_tokens = len(self.pbr_setting)
+ self.inner_dim = out_dim if out_dim is not None else dim_head * heads
+ self.inner_kv_dim = self.inner_dim if kv_heads is None else dim_head * kv_heads
+ self.query_dim = query_dim
+ self.use_bias = bias
+ self.is_cross_attention = cross_attention_dim is not None
+ self.cross_attention_dim = cross_attention_dim if cross_attention_dim is not None else query_dim
+ self.upcast_attention = upcast_attention
+ self.upcast_softmax = upcast_softmax
+ self.rescale_output_factor = rescale_output_factor
+ self.residual_connection = residual_connection
+ self.dropout = dropout
+ self.fused_projections = False
+ self.out_dim = out_dim if out_dim is not None else query_dim
+ self.out_context_dim = out_context_dim if out_context_dim is not None else query_dim
+ self.context_pre_only = context_pre_only
+ self.pre_only = pre_only
+ self.is_causal = is_causal
+ self._from_deprecated_attn_block = _from_deprecated_attn_block
+ self.scale_qk = scale_qk
+ self.scale = dim_head**-0.5 if self.scale_qk else 1.0
+ self.heads = out_dim // dim_head if out_dim is not None else heads
+ self.sliceable_head_dim = heads
+ self.added_kv_proj_dim = added_kv_proj_dim
+ self.only_cross_attention = only_cross_attention
+ self.added_proj_bias = added_proj_bias
+
+ # Validation
+ if self.added_kv_proj_dim is None and self.only_cross_attention:
+ raise ValueError(
+ "`only_cross_attention` can only be set to True if `added_kv_proj_dim` is not None."
+ "Make sure to set either `only_cross_attention=False` or define `added_kv_proj_dim`."
+ )
+
+ def register_pbr_modules(self, module_types: List[str], **kwargs):
+ """
+ Generic PBR module registration to eliminate code repetition.
+
+ Dynamically registers PyTorch modules for different PBR material types
+ based on the specified module types and PBR settings.
+
+ Args:
+ module_types: List of module types to register ("qkv", "v_only", "out", "add_kv")
+ **kwargs: Additional arguments for module configuration
+ """
+ for pbr_token in self.pbr_setting:
+ if pbr_token == "albedo":
+ continue
+
+ for module_type in module_types:
+ if module_type == "qkv":
+ self.register_module(
+ f"to_q_{pbr_token}", nn.Linear(self.query_dim, self.inner_dim, bias=self.use_bias)
+ )
+ self.register_module(
+ f"to_k_{pbr_token}", nn.Linear(self.cross_attention_dim, self.inner_dim, bias=self.use_bias)
+ )
+ self.register_module(
+ f"to_v_{pbr_token}", nn.Linear(self.cross_attention_dim, self.inner_dim, bias=self.use_bias)
+ )
+ elif module_type == "v_only":
+ self.register_module(
+ f"to_v_{pbr_token}", nn.Linear(self.cross_attention_dim, self.inner_dim, bias=self.use_bias)
+ )
+ elif module_type == "out":
+ if not self.pre_only:
+ self.register_module(
+ f"to_out_{pbr_token}",
+ nn.ModuleList(
+ [
+ nn.Linear(self.inner_dim, self.out_dim, bias=kwargs.get("out_bias", True)),
+ nn.Dropout(self.dropout),
+ ]
+ ),
+ )
+ else:
+ self.register_module(f"to_out_{pbr_token}", None)
+ elif module_type == "add_kv":
+ if self.added_kv_proj_dim is not None:
+ self.register_module(
+ f"add_k_proj_{pbr_token}",
+ nn.Linear(self.added_kv_proj_dim, self.inner_kv_dim, bias=self.added_proj_bias),
+ )
+ self.register_module(
+ f"add_v_proj_{pbr_token}",
+ nn.Linear(self.added_kv_proj_dim, self.inner_kv_dim, bias=self.added_proj_bias),
+ )
+ else:
+ self.register_module(f"add_k_proj_{pbr_token}", None)
+ self.register_module(f"add_v_proj_{pbr_token}", None)
+
+
+# Rotary Position Embedding utilities (specialized for PoseRoPE)
+class RotaryEmbedding:
+ """
+ Rotary position embedding utilities for 3D spatial attention.
+
+ Provides functions to compute and apply rotary position embeddings (RoPE)
+ for 1D, 3D spatial coordinates used in 3D-aware attention mechanisms.
+ """
+
+ @staticmethod
+ def get_1d_rotary_pos_embed(dim: int, pos: torch.Tensor, theta: float = 10000.0, linear_factor=1.0, ntk_factor=1.0):
+ """
+ Compute 1D rotary position embeddings.
+
+ Args:
+ dim: Embedding dimension (must be even)
+ pos: Position tensor
+ theta: Base frequency for rotary embeddings
+ linear_factor: Linear scaling factor
+ ntk_factor: NTK (Neural Tangent Kernel) scaling factor
+
+ Returns:
+ Tuple of (cos_embeddings, sin_embeddings)
+ """
+ assert dim % 2 == 0
+ theta = theta * ntk_factor
+ freqs = (
+ 1.0
+ / (theta ** (torch.arange(0, dim, 2, dtype=pos.dtype, device=pos.device)[: (dim // 2)] / dim))
+ / linear_factor
+ )
+ freqs = torch.outer(pos, freqs)
+ freqs_cos = freqs.cos().repeat_interleave(2, dim=1).float()
+ freqs_sin = freqs.sin().repeat_interleave(2, dim=1).float()
+ return freqs_cos, freqs_sin
+
+ @staticmethod
+ def get_3d_rotary_pos_embed(position, embed_dim, voxel_resolution, theta: int = 10000):
+ """
+ Compute 3D rotary position embeddings for spatial coordinates.
+
+ Args:
+ position: 3D position tensor with shape [..., 3]
+ embed_dim: Embedding dimension
+ voxel_resolution: Resolution of the voxel grid
+ theta: Base frequency for rotary embeddings
+
+ Returns:
+ Tuple of (cos_embeddings, sin_embeddings) for 3D positions
+ """
+ assert position.shape[-1] == 3
+ dim_xy = embed_dim // 8 * 3
+ dim_z = embed_dim // 8 * 2
+
+ grid = torch.arange(voxel_resolution, dtype=torch.float32, device=position.device)
+ freqs_xy = RotaryEmbedding.get_1d_rotary_pos_embed(dim_xy, grid, theta=theta)
+ freqs_z = RotaryEmbedding.get_1d_rotary_pos_embed(dim_z, grid, theta=theta)
+
+ xy_cos, xy_sin = freqs_xy
+ z_cos, z_sin = freqs_z
+
+ embed_flattn = position.view(-1, position.shape[-1])
+ x_cos = xy_cos[embed_flattn[:, 0], :]
+ x_sin = xy_sin[embed_flattn[:, 0], :]
+ y_cos = xy_cos[embed_flattn[:, 1], :]
+ y_sin = xy_sin[embed_flattn[:, 1], :]
+ z_cos = z_cos[embed_flattn[:, 2], :]
+ z_sin = z_sin[embed_flattn[:, 2], :]
+
+ cos = torch.cat((x_cos, y_cos, z_cos), dim=-1)
+ sin = torch.cat((x_sin, y_sin, z_sin), dim=-1)
+
+ cos = cos.view(*position.shape[:-1], embed_dim)
+ sin = sin.view(*position.shape[:-1], embed_dim)
+ return cos, sin
+
+ @staticmethod
+ def apply_rotary_emb(x: torch.Tensor, freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]]):
+ """
+ Apply rotary position embeddings to input tensor.
+
+ Args:
+ x: Input tensor to apply rotary embeddings to
+ freqs_cis: Tuple of (cos_embeddings, sin_embeddings) or single tensor
+
+ Returns:
+ Tensor with rotary position embeddings applied
+ """
+ cos, sin = freqs_cis
+ cos, sin = cos.to(x.device), sin.to(x.device)
+ cos = cos.unsqueeze(1)
+ sin = sin.unsqueeze(1)
+
+ x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1)
+ x_rotated = torch.stack([-x_imag, x_real], dim=-1).flatten(3)
+
+ out = (x.float() * cos + x_rotated.float() * sin).to(x.dtype)
+ return out
+
+
+# Core attention processing logic (eliminating major duplication)
+class AttnCore:
+ """
+ Core attention processing logic shared across processors.
+
+ This class provides the fundamental attention computation pipeline
+ that can be reused across different attention processor implementations.
+ """
+
+ @staticmethod
+ def process_attention_base(
+ attn: Attention,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ temb: Optional[torch.Tensor] = None,
+ get_qkv_fn: Callable = None,
+ apply_rope_fn: Optional[Callable] = None,
+ **kwargs,
+ ):
+ """
+ Generic attention processing core shared across different processors.
+
+ This function implements the common attention computation pipeline including:
+ 1. Hidden state preprocessing
+ 2. Attention mask preparation
+ 3. Q/K/V computation via provided function
+ 4. Tensor reshaping for multi-head attention
+ 5. Optional normalization and RoPE application
+ 6. Scaled dot-product attention computation
+
+ Args:
+ attn: Attention module instance
+ hidden_states: Input hidden states tensor
+ encoder_hidden_states: Optional encoder hidden states for cross-attention
+ attention_mask: Optional attention mask tensor
+ temb: Optional temporal embedding tensor
+ get_qkv_fn: Function to compute Q, K, V tensors
+ apply_rope_fn: Optional function to apply rotary position embeddings
+ **kwargs: Additional keyword arguments passed to subfunctions
+
+ Returns:
+ Tuple containing (attention_output, residual, input_ndim, shape_info,
+ batch_size, num_heads, head_dim)
+ """
+ # Prepare hidden states
+ hidden_states, residual, input_ndim, shape_info = AttnUtils.prepare_hidden_states(hidden_states, attn, temb)
+
+ batch_size, sequence_length, _ = (
+ hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
+ )
+
+ # Prepare attention mask
+ attention_mask = AttnUtils.prepare_attention_mask(attention_mask, attn, sequence_length, batch_size)
+
+ # Get Q, K, V
+ if encoder_hidden_states is None:
+ encoder_hidden_states = hidden_states
+ elif attn.norm_cross:
+ encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
+
+ query, key, value = get_qkv_fn(attn, hidden_states, encoder_hidden_states, **kwargs)
+
+ # Reshape for attention
+ inner_dim = key.shape[-1]
+ head_dim = inner_dim // attn.heads
+
+ query = AttnUtils.reshape_qkv_for_attention(query, batch_size, attn.heads, head_dim)
+ key = AttnUtils.reshape_qkv_for_attention(key, batch_size, attn.heads, head_dim)
+ value = AttnUtils.reshape_qkv_for_attention(value, batch_size, attn.heads, value.shape[-1] // attn.heads)
+
+ # Apply normalization
+ query, key = AttnUtils.apply_norms(query, key, getattr(attn, "norm_q", None), getattr(attn, "norm_k", None))
+
+ # Apply RoPE if provided
+ if apply_rope_fn is not None:
+ query, key = apply_rope_fn(query, key, head_dim, **kwargs)
+
+ # Compute attention
+ hidden_states = F.scaled_dot_product_attention(
+ query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
+ )
+
+ return hidden_states, residual, input_ndim, shape_info, batch_size, attn.heads, head_dim
+
+
+# Specific processor implementations (minimal unique code)
+class PoseRoPEAttnProcessor2_0:
+ """
+ Attention processor with Rotary Position Encoding (RoPE) for 3D spatial awareness.
+
+ This processor extends standard attention with 3D rotary position embeddings
+ to provide spatial awareness for 3D scene understanding tasks.
+ """
+
+ def __init__(self):
+ """Initialize the RoPE attention processor."""
+ AttnUtils.check_pytorch_compatibility()
+
+ def __call__(
+ self,
+ attn: Attention,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_indices: Dict = None,
+ temb: Optional[torch.Tensor] = None,
+ n_pbrs=1,
+ *args,
+ **kwargs,
+ ) -> torch.Tensor:
+ """
+ Apply RoPE-enhanced attention computation.
+
+ Args:
+ attn: Attention module instance
+ hidden_states: Input hidden states tensor
+ encoder_hidden_states: Optional encoder hidden states for cross-attention
+ attention_mask: Optional attention mask tensor
+ position_indices: Dictionary containing 3D position information for RoPE
+ temb: Optional temporal embedding tensor
+ n_pbrs: Number of PBR material types
+ *args: Additional positional arguments
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Attention output tensor with applied rotary position encodings
+ """
+ AttnUtils.handle_deprecation_warning(args, kwargs)
+
+ def get_qkv(attn, hidden_states, encoder_hidden_states, **kwargs):
+ return attn.to_q(hidden_states), attn.to_k(encoder_hidden_states), attn.to_v(encoder_hidden_states)
+
+ def apply_rope(query, key, head_dim, **kwargs):
+ if position_indices is not None:
+ if head_dim in position_indices:
+ image_rotary_emb = position_indices[head_dim]
+ else:
+ image_rotary_emb = RotaryEmbedding.get_3d_rotary_pos_embed(
+ rearrange(
+ position_indices["voxel_indices"].unsqueeze(1).repeat(1, n_pbrs, 1, 1),
+ "b n_pbrs l c -> (b n_pbrs) l c",
+ ),
+ head_dim,
+ voxel_resolution=position_indices["voxel_resolution"],
+ )
+ position_indices[head_dim] = image_rotary_emb
+
+ query = RotaryEmbedding.apply_rotary_emb(query, image_rotary_emb)
+ key = RotaryEmbedding.apply_rotary_emb(key, image_rotary_emb)
+ return query, key
+
+ # Core attention processing
+ hidden_states, residual, input_ndim, shape_info, batch_size, heads, head_dim = AttnCore.process_attention_base(
+ attn,
+ hidden_states,
+ encoder_hidden_states,
+ attention_mask,
+ temb,
+ get_qkv_fn=get_qkv,
+ apply_rope_fn=apply_rope,
+ position_indices=position_indices,
+ n_pbrs=n_pbrs,
+ )
+
+ # Finalize output
+ hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, heads * head_dim)
+ hidden_states = hidden_states.to(hidden_states.dtype)
+
+ return AttnUtils.finalize_output(hidden_states, input_ndim, shape_info, attn, residual, attn.to_out)
+
+
+class SelfAttnProcessor2_0(BaseAttnProcessor):
+ """
+ Self-attention processor with PBR (Physically Based Rendering) material support.
+
+ This processor handles multiple PBR material types (e.g., albedo, metallic-roughness)
+ with separate attention computation paths for each material type.
+ """
+
+ def __init__(self, **kwargs):
+ """
+ Initialize self-attention processor with PBR support.
+
+ Args:
+ **kwargs: Arguments passed to BaseAttnProcessor initialization
+ """
+ super().__init__(**kwargs)
+ self.register_pbr_modules(["qkv", "out", "add_kv"], **kwargs)
+
+ def process_single(
+ self,
+ attn: Attention,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ temb: Optional[torch.Tensor] = None,
+ token: Literal["albedo", "mr"] = "albedo",
+ multiple_devices=False,
+ *args,
+ **kwargs,
+ ):
+ """
+ Process attention for a single PBR material type.
+
+ Args:
+ attn: Attention module instance
+ hidden_states: Input hidden states tensor
+ encoder_hidden_states: Optional encoder hidden states for cross-attention
+ attention_mask: Optional attention mask tensor
+ temb: Optional temporal embedding tensor
+ token: PBR material type to process ("albedo", "mr", etc.)
+ multiple_devices: Whether to use multiple GPU devices
+ *args: Additional positional arguments
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Processed attention output for the specified PBR material type
+ """
+ target = attn if token == "albedo" else attn.processor
+ token_suffix = "" if token == "albedo" else "_" + token
+
+ # Device management (if needed)
+ if multiple_devices:
+ device = torch.device("cuda:0") if token == "albedo" else torch.device("cuda:1")
+ for attr in [f"to_q{token_suffix}", f"to_k{token_suffix}", f"to_v{token_suffix}", f"to_out{token_suffix}"]:
+ getattr(target, attr).to(device)
+
+ def get_qkv(attn, hidden_states, encoder_hidden_states, **kwargs):
+ return (
+ getattr(target, f"to_q{token_suffix}")(hidden_states),
+ getattr(target, f"to_k{token_suffix}")(encoder_hidden_states),
+ getattr(target, f"to_v{token_suffix}")(encoder_hidden_states),
+ )
+
+ # Core processing using shared logic
+ hidden_states, residual, input_ndim, shape_info, batch_size, heads, head_dim = AttnCore.process_attention_base(
+ attn, hidden_states, encoder_hidden_states, attention_mask, temb, get_qkv_fn=get_qkv
+ )
+
+ # Finalize
+ hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, heads * head_dim)
+ hidden_states = hidden_states.to(hidden_states.dtype)
+
+ return AttnUtils.finalize_output(
+ hidden_states, input_ndim, shape_info, attn, residual, getattr(target, f"to_out{token_suffix}")
+ )
+
+ def __call__(
+ self,
+ attn: Attention,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ temb: Optional[torch.Tensor] = None,
+ *args,
+ **kwargs,
+ ) -> torch.Tensor:
+ """
+ Apply self-attention with PBR material processing.
+
+ Processes multiple PBR material types sequentially, applying attention
+ computation for each material type separately and combining results.
+
+ Args:
+ attn: Attention module instance
+ hidden_states: Input hidden states tensor with PBR dimension
+ encoder_hidden_states: Optional encoder hidden states for cross-attention
+ attention_mask: Optional attention mask tensor
+ temb: Optional temporal embedding tensor
+ *args: Additional positional arguments
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Combined attention output for all PBR material types
+ """
+ AttnUtils.handle_deprecation_warning(args, kwargs)
+
+ B = hidden_states.size(0)
+ pbr_hidden_states = torch.split(hidden_states, 1, dim=1)
+
+ # Process each PBR setting
+ results = []
+ for token, pbr_hs in zip(self.pbr_setting, pbr_hidden_states):
+ processed_hs = rearrange(pbr_hs, "b n_pbrs n l c -> (b n_pbrs n) l c").to("cuda:0")
+ result = self.process_single(attn, processed_hs, None, attention_mask, temb, token, False)
+ results.append(result)
+
+ outputs = [rearrange(result, "(b n_pbrs n) l c -> b n_pbrs n l c", b=B, n_pbrs=1) for result in results]
+ return torch.cat(outputs, dim=1)
+
+
+class RefAttnProcessor2_0(BaseAttnProcessor):
+ """
+ Reference attention processor with shared value computation across PBR materials.
+
+ This processor computes query and key once, but uses separate value projections
+ for different PBR material types, enabling efficient multi-material processing.
+ """
+
+ def __init__(self, **kwargs):
+ """
+ Initialize reference attention processor.
+
+ Args:
+ **kwargs: Arguments passed to BaseAttnProcessor initialization
+ """
+ super().__init__(**kwargs)
+ self.pbr_settings = self.pbr_setting # Alias for compatibility
+ self.register_pbr_modules(["v_only", "out"], **kwargs)
+
+ def __call__(
+ self,
+ attn: Attention,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ temb: Optional[torch.Tensor] = None,
+ *args,
+ **kwargs,
+ ) -> torch.Tensor:
+ """
+ Apply reference attention with shared Q/K and separate V projections.
+
+ This method computes query and key tensors once and reuses them across
+ all PBR material types, while using separate value projections for each
+ material type to maintain material-specific information.
+
+ Args:
+ attn: Attention module instance
+ hidden_states: Input hidden states tensor
+ encoder_hidden_states: Optional encoder hidden states for cross-attention
+ attention_mask: Optional attention mask tensor
+ temb: Optional temporal embedding tensor
+ *args: Additional positional arguments
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Stacked attention output for all PBR material types
+ """
+ AttnUtils.handle_deprecation_warning(args, kwargs)
+
+ def get_qkv(attn, hidden_states, encoder_hidden_states, **kwargs):
+ query = attn.to_q(hidden_states)
+ key = attn.to_k(encoder_hidden_states)
+
+ # Concatenate values from all PBR settings
+ value_list = [attn.to_v(encoder_hidden_states)]
+ for token in ["_" + token for token in self.pbr_settings if token != "albedo"]:
+ value_list.append(getattr(attn.processor, f"to_v{token}")(encoder_hidden_states))
+ value = torch.cat(value_list, dim=-1)
+
+ return query, key, value
+
+ # Core processing
+ hidden_states, residual, input_ndim, shape_info, batch_size, heads, head_dim = AttnCore.process_attention_base(
+ attn, hidden_states, encoder_hidden_states, attention_mask, temb, get_qkv_fn=get_qkv
+ )
+
+ # Split and process each PBR setting output
+ hidden_states_list = torch.split(hidden_states, head_dim, dim=-1)
+ output_hidden_states_list = []
+
+ for i, hs in enumerate(hidden_states_list):
+ hs = hs.transpose(1, 2).reshape(batch_size, -1, heads * head_dim).to(hs.dtype)
+ token_suffix = "_" + self.pbr_settings[i] if self.pbr_settings[i] != "albedo" else ""
+ target = attn if self.pbr_settings[i] == "albedo" else attn.processor
+
+ hs = AttnUtils.finalize_output(
+ hs, input_ndim, shape_info, attn, residual, getattr(target, f"to_out{token_suffix}")
+ )
+ output_hidden_states_list.append(hs)
+
+ return torch.stack(output_hidden_states_list, dim=1)
diff --git a/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/model.py b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..f98ca7e73a5fdc59d6fc1afb0b2f1f6eb75be169
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/model.py
@@ -0,0 +1,622 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+
+# import ipdb
+import numpy as np
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import pytorch_lightning as pl
+from tqdm import tqdm
+from torchvision.transforms import v2
+from torchvision.utils import make_grid, save_image
+from einops import rearrange
+
+from diffusers import (
+ DiffusionPipeline,
+ EulerAncestralDiscreteScheduler,
+ DDPMScheduler,
+ UNet2DConditionModel,
+ ControlNetModel,
+)
+
+from .modules import Dino_v2, UNet2p5DConditionModel
+import math
+
+
+def extract_into_tensor(a, t, x_shape):
+ b, *_ = t.shape
+ out = a.gather(-1, t)
+ return out.reshape(b, *((1,) * (len(x_shape) - 1)))
+
+
+class HunyuanPaint(pl.LightningModule):
+ def __init__(
+ self,
+ stable_diffusion_config,
+ control_net_config=None,
+ num_view=6,
+ view_size=320,
+ drop_cond_prob=0.1,
+ with_normal_map=None,
+ with_position_map=None,
+ pbr_settings=["albedo", "mr"],
+ **kwargs,
+ ):
+ """Initializes the HunyuanPaint Lightning Module.
+
+ Args:
+ stable_diffusion_config: Configuration for loading the Stable Diffusion pipeline
+ control_net_config: Configuration for ControlNet (optional)
+ num_view: Number of views to process
+ view_size: Size of input views (height/width)
+ drop_cond_prob: Probability of dropping conditioning input during training
+ with_normal_map: Flag indicating whether normal maps are used
+ with_position_map: Flag indicating whether position maps are used
+ pbr_settings: List of PBR materials to generate (e.g., albedo, metallic-roughness)
+ **kwargs: Additional keyword arguments
+ """
+ super(HunyuanPaint, self).__init__()
+
+ self.num_view = num_view
+ self.view_size = view_size
+ self.drop_cond_prob = drop_cond_prob
+ self.pbr_settings = pbr_settings
+
+ # init modules
+ pipeline = DiffusionPipeline.from_pretrained(**stable_diffusion_config)
+ pipeline.set_pbr_settings(self.pbr_settings)
+ pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(
+ pipeline.scheduler.config, timestep_spacing="trailing"
+ )
+
+ self.with_normal_map = with_normal_map
+ self.with_position_map = with_position_map
+
+ self.pipeline = pipeline
+
+ self.pipeline.vae.use_slicing = True
+
+ train_sched = DDPMScheduler.from_config(self.pipeline.scheduler.config)
+
+ if isinstance(self.pipeline.unet, UNet2DConditionModel):
+ self.pipeline.unet = UNet2p5DConditionModel(
+ self.pipeline.unet, train_sched, self.pipeline.scheduler, self.pbr_settings
+ )
+ self.train_scheduler = train_sched # use ddpm scheduler during training
+
+ self.register_schedule()
+
+ pipeline.set_learned_parameters()
+
+ if control_net_config is not None:
+ pipeline.unet = pipeline.unet.bfloat16().requires_grad_(control_net_config.train_unet)
+ self.pipeline.add_controlnet(
+ ControlNetModel.from_pretrained(control_net_config.pretrained_model_name_or_path),
+ conditioning_scale=0.75,
+ )
+
+ self.unet = pipeline.unet
+
+ self.pipeline.set_progress_bar_config(disable=True)
+ self.pipeline.vae = self.pipeline.vae.bfloat16()
+ self.pipeline.text_encoder = self.pipeline.text_encoder.bfloat16()
+
+ if self.unet.use_dino:
+ self.dino_v2 = Dino_v2("facebook/dinov2-giant")
+ self.dino_v2 = self.dino_v2.bfloat16()
+
+ self.validation_step_outputs = []
+
+ def register_schedule(self):
+
+ self.num_timesteps = self.train_scheduler.config.num_train_timesteps
+
+ betas = self.train_scheduler.betas.detach().cpu()
+
+ alphas = 1.0 - betas
+ alphas_cumprod = torch.cumprod(alphas, dim=0)
+ alphas_cumprod_prev = torch.cat([torch.ones(1, dtype=torch.float64), alphas_cumprod[:-1]], 0)
+
+ self.register_buffer("betas", betas.float())
+ self.register_buffer("alphas_cumprod", alphas_cumprod.float())
+ self.register_buffer("alphas_cumprod_prev", alphas_cumprod_prev.float())
+
+ # calculations for diffusion q(x_t | x_{t-1}) and others
+ self.register_buffer("sqrt_alphas_cumprod", torch.sqrt(alphas_cumprod).float())
+ self.register_buffer("sqrt_one_minus_alphas_cumprod", torch.sqrt(1 - alphas_cumprod).float())
+
+ self.register_buffer("sqrt_recip_alphas_cumprod", torch.sqrt(1.0 / alphas_cumprod).float())
+ self.register_buffer("sqrt_recipm1_alphas_cumprod", torch.sqrt(1.0 / alphas_cumprod - 1).float())
+
+ def on_fit_start(self):
+ device = torch.device(f"cuda:{self.local_rank}")
+ self.pipeline.to(device)
+ if self.global_rank == 0:
+ os.makedirs(os.path.join(self.logdir, "images_val"), exist_ok=True)
+
+ def prepare_batch_data(self, batch):
+ """Preprocesses a batch of input data for training/inference.
+
+ Args:
+ batch: Raw input batch dictionary
+
+ Returns:
+ tuple: Contains:
+ - cond_imgs: Primary conditioning images (B, 1, C, H, W)
+ - cond_imgs_another: Secondary conditioning images (B, 1, C, H, W)
+ - target_imgs: Dictionary of target PBR images resized and clamped
+ - images_normal: Preprocessed normal maps (if available)
+ - images_position: Preprocessed position maps (if available)
+ """
+
+ images_cond = batch["images_cond"].to(self.device) # (B, M, C, H, W), where M is the number of reference images
+ cond_imgs, cond_imgs_another = images_cond[:, 0:1, ...], images_cond[:, 1:2, ...]
+
+ cond_size = self.view_size
+ cond_imgs = v2.functional.resize(cond_imgs, cond_size, interpolation=3, antialias=True).clamp(0, 1)
+ cond_imgs_another = v2.functional.resize(cond_imgs_another, cond_size, interpolation=3, antialias=True).clamp(
+ 0, 1
+ )
+
+ target_imgs = {}
+ for pbr_token in self.pbr_settings:
+ target_imgs[pbr_token] = batch[f"images_{pbr_token}"].to(self.device)
+ target_imgs[pbr_token] = v2.functional.resize(
+ target_imgs[pbr_token], self.view_size, interpolation=3, antialias=True
+ ).clamp(0, 1)
+
+ images_normal = None
+ if "images_normal" in batch:
+ images_normal = batch["images_normal"] # (B, N, C, H, W)
+ images_normal = v2.functional.resize(images_normal, self.view_size, interpolation=3, antialias=True).clamp(
+ 0, 1
+ )
+ images_normal = [images_normal]
+
+ images_position = None
+ if "images_position" in batch:
+ images_position = batch["images_position"] # (B, N, C, H, W)
+ images_position = v2.functional.resize(
+ images_position, self.view_size, interpolation=3, antialias=True
+ ).clamp(0, 1)
+ images_position = [images_position]
+
+ return cond_imgs, cond_imgs_another, target_imgs, images_normal, images_position
+
+ @torch.no_grad()
+ def forward_text_encoder(self, prompts):
+ device = next(self.pipeline.vae.parameters()).device
+ text_embeds = self.pipeline.encode_prompt(prompts, device, 1, False)[0]
+ return text_embeds
+
+ @torch.no_grad()
+ def encode_images(self, images):
+ """Encodes input images into latent representations using the VAE.
+
+ Handles both standard input (B, N, C, H, W) and PBR input (B, N_pbrs, N, C, H, W)
+ Maintains original batch structure in output latents.
+
+ Args:
+ images: Input images tensor
+
+ Returns:
+ torch.Tensor: Latent representations with original batch dimensions preserved
+ """
+
+ B = images.shape[0]
+ image_ndims = images.ndim
+ if image_ndims != 5:
+ N_pbrs, N = images.shape[1:3]
+ images = (
+ rearrange(images, "b n c h w -> (b n) c h w")
+ if image_ndims == 5
+ else rearrange(images, "b n_pbrs n c h w -> (b n_pbrs n) c h w")
+ )
+ dtype = next(self.pipeline.vae.parameters()).dtype
+
+ images = (images - 0.5) * 2.0
+ posterior = self.pipeline.vae.encode(images.to(dtype)).latent_dist
+ latents = posterior.sample() * self.pipeline.vae.config.scaling_factor
+
+ latents = (
+ rearrange(latents, "(b n) c h w -> b n c h w", b=B)
+ if image_ndims == 5
+ else rearrange(latents, "(b n_pbrs n) c h w -> b n_pbrs n c h w", b=B, n_pbrs=N_pbrs)
+ )
+
+ return latents
+
+ def forward_unet(self, latents, t, **cached_condition):
+ """Runs the UNet model to predict noise/latent residuals.
+
+ Args:
+ latents: Noisy latent representations (B, C, H, W)
+ t: Timestep tensor (B,)
+ **cached_condition: Dictionary of conditioning inputs (text embeds, reference images, etc)
+
+ Returns:
+ torch.Tensor: UNet output (predicted noise or velocity)
+ """
+
+ dtype = next(self.unet.parameters()).dtype
+ latents = latents.to(dtype)
+ shading_embeds = cached_condition["shading_embeds"]
+ pred_noise = self.pipeline.unet(latents, t, encoder_hidden_states=shading_embeds, **cached_condition)
+ return pred_noise[0]
+
+ def predict_start_from_z_and_v(self, x_t, t, v):
+ """
+ Predicts clean image (x0) from noisy latents (x_t) and
+ velocity prediction (v) using the v-prediction formula.
+
+ Args:
+ x_t: Noisy latents at timestep t
+ t: Current timestep
+ v: Predicted velocity (v) from UNet
+
+ Returns:
+ torch.Tensor: Predicted clean image (x0)
+ """
+
+ return (
+ extract_into_tensor(self.sqrt_alphas_cumprod, t, x_t.shape) * x_t
+ - extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_t.shape) * v
+ )
+
+ def get_v(self, x, noise, t):
+ """Computes the target velocity (v) for v-prediction training.
+
+ Args:
+ x: Clean latents (x0)
+ noise: Added noise
+ t: Current timestep
+
+ Returns:
+ torch.Tensor: Target velocity
+ """
+
+ return (
+ extract_into_tensor(self.sqrt_alphas_cumprod, t, x.shape) * noise
+ - extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x.shape) * x
+ )
+
+ def training_step(self, batch, batch_idx):
+ """Performs a single training step with both conditioning paths.
+
+ Implements:
+ 1. Dual-conditioning path training (main ref + secondary ref)
+ 2. Velocity-prediction with consistency loss
+ 3. Conditional dropout for robust learning
+ 4. PBR-specific losses (albedo/metallic-roughness)
+
+ Args:
+ batch: Input batch from dataloader
+ batch_idx: Index of current batch
+
+ Returns:
+ torch.Tensor: Combined loss value
+ """
+
+ cond_imgs, cond_imgs_another, target_imgs, normal_imgs, position_imgs = self.prepare_batch_data(batch)
+
+ B, N_ref = cond_imgs.shape[:2]
+ _, N_gen, _, H, W = target_imgs["albedo"].shape
+ N_pbrs = len(self.pbr_settings)
+ t = torch.randint(0, self.num_timesteps, size=(B,)).long().to(self.device)
+ t = t.unsqueeze(-1).repeat(1, N_pbrs, N_gen)
+ t = rearrange(t, "b n_pbrs n -> (b n_pbrs n)")
+
+ all_target_pbrs = []
+ for pbr_token in self.pbr_settings:
+ all_target_pbrs.append(target_imgs[pbr_token])
+ all_target_pbrs = torch.stack(all_target_pbrs, dim=0).transpose(1, 0)
+ gen_latents = self.encode_images(all_target_pbrs) #! B, N_pbrs N C H W
+ ref_latents = self.encode_images(cond_imgs) #! B, M, C, H, W
+ ref_latents_another = self.encode_images(cond_imgs_another) #! B, M, C, H, W
+
+ all_shading_tokens = []
+ for token in self.pbr_settings:
+ if token in ["albedo", "mr"]:
+ all_shading_tokens.append(
+ getattr(self.unet, f"learned_text_clip_{token}").unsqueeze(dim=0).repeat(B, 1, 1)
+ )
+ shading_embeds = torch.stack(all_shading_tokens, dim=1)
+
+ if self.unet.use_dino:
+ dino_hidden_states = self.dino_v2(cond_imgs[:, :1, ...])
+ dino_hidden_states_another = self.dino_v2(cond_imgs_another[:, :1, ...])
+
+ gen_latents = rearrange(gen_latents, "b n_pbrs n c h w -> (b n_pbrs n) c h w")
+ noise = torch.randn_like(gen_latents).to(self.device)
+ latents_noisy = self.train_scheduler.add_noise(gen_latents, noise, t).to(self.device)
+ latents_noisy = rearrange(latents_noisy, "(b n_pbrs n) c h w -> b n_pbrs n c h w", b=B, n_pbrs=N_pbrs)
+
+ cached_condition = {}
+
+ if normal_imgs is not None:
+ normal_embeds = self.encode_images(normal_imgs[0])
+ cached_condition["embeds_normal"] = normal_embeds #! B, N, C, H, W
+
+ if position_imgs is not None:
+ position_embeds = self.encode_images(position_imgs[0])
+ cached_condition["embeds_position"] = position_embeds #! B, N, C, H, W
+ cached_condition["position_maps"] = position_imgs[0] #! B, N, C, H, W
+
+ for b in range(B):
+ prob = np.random.rand()
+ if prob < self.drop_cond_prob:
+ if "normal_imgs" in cached_condition:
+ cached_condition["embeds_normal"][b, ...] = torch.zeros_like(
+ cached_condition["embeds_normal"][b, ...]
+ )
+ if "position_imgs" in cached_condition:
+ cached_condition["embeds_position"][b, ...] = torch.zeros_like(
+ cached_condition["embeds_position"][b, ...]
+ )
+
+ prob = np.random.rand()
+ if prob < self.drop_cond_prob:
+ if "position_maps" in cached_condition:
+ cached_condition["position_maps"][b, ...] = torch.zeros_like(
+ cached_condition["position_maps"][b, ...]
+ )
+
+ prob = np.random.rand()
+ if prob < self.drop_cond_prob:
+ dino_hidden_states[b, ...] = torch.zeros_like(dino_hidden_states[b, ...])
+ prob = np.random.rand()
+ if prob < self.drop_cond_prob:
+ dino_hidden_states_another[b, ...] = torch.zeros_like(dino_hidden_states_another[b, ...])
+
+ # MVA & Ref Attention
+ prob = np.random.rand()
+ cached_condition["mva_scale"] = 1.0
+ cached_condition["ref_scale"] = 1.0
+ if prob < self.drop_cond_prob:
+ cached_condition["mva_scale"] = 0.0
+ cached_condition["ref_scale"] = 0.0
+ elif prob > 1.0 - self.drop_cond_prob:
+ prob = np.random.rand()
+ if prob < 0.5:
+ cached_condition["mva_scale"] = 0.0
+ else:
+ cached_condition["ref_scale"] = 0.0
+ else:
+ pass
+
+ if self.train_scheduler.config.prediction_type == "v_prediction":
+
+ cached_condition["shading_embeds"] = shading_embeds
+ cached_condition["ref_latents"] = ref_latents
+ cached_condition["dino_hidden_states"] = dino_hidden_states
+ v_pred = self.forward_unet(latents_noisy, t, **cached_condition)
+ v_pred_albedo, v_pred_mr = torch.split(
+ rearrange(
+ v_pred, "(b n_pbr n) c h w -> b n_pbr n c h w", n_pbr=len(self.pbr_settings), n=self.num_view
+ ),
+ 1,
+ dim=1,
+ )
+ v_target = self.get_v(gen_latents, noise, t)
+ v_target_albedo, v_target_mr = torch.split(
+ rearrange(
+ v_target, "(b n_pbr n) c h w -> b n_pbr n c h w", n_pbr=len(self.pbr_settings), n=self.num_view
+ ),
+ 1,
+ dim=1,
+ )
+
+ albedo_loss_1, _ = self.compute_loss(v_pred_albedo, v_target_albedo)
+ mr_loss_1, _ = self.compute_loss(v_pred_mr, v_target_mr)
+
+ cached_condition["ref_latents"] = ref_latents_another
+ cached_condition["dino_hidden_states"] = dino_hidden_states_another
+ v_pred_another = self.forward_unet(latents_noisy, t, **cached_condition)
+ v_pred_another_albedo, v_pred_another_mr = torch.split(
+ rearrange(
+ v_pred_another,
+ "(b n_pbr n) c h w -> b n_pbr n c h w",
+ n_pbr=len(self.pbr_settings),
+ n=self.num_view,
+ ),
+ 1,
+ dim=1,
+ )
+
+ albedo_loss_2, _ = self.compute_loss(v_pred_another_albedo, v_target_albedo)
+ mr_loss_2, _ = self.compute_loss(v_pred_another_mr, v_target_mr)
+
+ consistency_loss, _ = self.compute_loss(v_pred_another, v_pred)
+
+ albedo_loss = (albedo_loss_1 + albedo_loss_2) * 0.5
+ mr_loss = (mr_loss_1 + mr_loss_2) * 0.5
+
+ log_loss_dict = {}
+ log_loss_dict.update({f"train/albedo_loss": albedo_loss})
+ log_loss_dict.update({f"train/mr_loss": mr_loss})
+ log_loss_dict.update({f"train/cons_loss": consistency_loss})
+
+ loss_dict = log_loss_dict
+
+ elif self.train_scheduler.config.prediction_type == "epsilon":
+ e_pred = self.forward_unet(latents_noisy, t, **cached_condition)
+ loss, loss_dict = self.compute_loss(e_pred, noise)
+ else:
+ raise f"No {self.train_scheduler.config.prediction_type}"
+
+ # logging
+ self.log_dict(loss_dict, prog_bar=True, logger=True, on_step=True, on_epoch=True)
+ self.log("global_step", self.global_step, prog_bar=True, logger=True, on_step=True, on_epoch=False)
+ lr = self.optimizers().param_groups[0]["lr"]
+ self.log("lr_abs", lr, prog_bar=True, logger=True, on_step=True, on_epoch=False)
+
+ return 0.85 * (albedo_loss + mr_loss) + 0.15 * consistency_loss
+
+ def compute_loss(self, noise_pred, noise_gt):
+ loss = F.mse_loss(noise_pred, noise_gt)
+ prefix = "train"
+ loss_dict = {}
+ loss_dict.update({f"{prefix}/loss": loss})
+ return loss, loss_dict
+
+ @torch.no_grad()
+ def validation_step(self, batch, batch_idx):
+ """Performs validation on a single batch.
+
+ Generates predicted images using:
+ 1. Reference conditioning images
+ 2. Optional normal/position maps
+ 3. Frozen DINO features (if enabled)
+ 4. Text prompt conditioning
+
+ Compares predictions against ground truth targets and prepares visualization.
+ Stores results for epoch-level aggregation.
+
+ Args:
+ batch: Input batch from validation dataloader
+ batch_idx: Index of current batch
+ """
+ # [Validation image generation and comparison logic...]
+ # Key steps:
+ # 1. Preprocess conditioning images to PIL format
+ # 2. Set up conditioning inputs (normal maps, position maps, DINO features)
+ # 3. Run pipeline inference with fixed prompt ("high quality")
+ # 4. Decode latent outputs to image space
+ # 5. Arrange predictions and ground truths for visualization
+
+ cond_imgs_tensor, _, target_imgs, normal_imgs, position_imgs = self.prepare_batch_data(batch)
+ resolution = self.view_size
+ image_pils = []
+ for i in range(cond_imgs_tensor.shape[0]):
+ image_pils.append([])
+ for j in range(cond_imgs_tensor.shape[1]):
+ image_pils[-1].append(v2.functional.to_pil_image(cond_imgs_tensor[i, j, ...]))
+
+ outputs, gts = [], []
+ for idx in range(len(image_pils)):
+ cond_imgs = image_pils[idx]
+
+ cached_condition = dict(num_in_batch=self.num_view, N_pbrs=len(self.pbr_settings))
+ if normal_imgs is not None:
+ cached_condition["images_normal"] = normal_imgs[0][idx, ...].unsqueeze(0)
+ if position_imgs is not None:
+ cached_condition["images_position"] = position_imgs[0][idx, ...].unsqueeze(0)
+ if self.pipeline.unet.use_dino:
+ dino_hidden_states = self.dino_v2([cond_imgs][0])
+ cached_condition["dino_hidden_states"] = dino_hidden_states
+
+ latent = self.pipeline(
+ cond_imgs,
+ prompt="high quality",
+ num_inference_steps=30,
+ output_type="latent",
+ height=resolution,
+ width=resolution,
+ **cached_condition,
+ ).images
+
+ image = self.pipeline.vae.decode(latent / self.pipeline.vae.config.scaling_factor, return_dict=False)[
+ 0
+ ] # [-1, 1]
+ image = (image * 0.5 + 0.5).clamp(0, 1)
+
+ image = rearrange(
+ image, "(b n_pbr n) c h w -> b n_pbr n c h w", n_pbr=len(self.pbr_settings), n=self.num_view
+ )
+ image = torch.cat((torch.ones_like(image[:, :, :1, ...]) * 0.5, image), dim=2)
+ image = rearrange(image, "b n_pbr n c h w -> (b n_pbr n) c h w")
+ image = rearrange(
+ image,
+ "(b n_pbr n) c h w -> b c (n_pbr h) (n w)",
+ b=1,
+ n_pbr=len(self.pbr_settings),
+ n=self.num_view + 1,
+ )
+ outputs.append(image)
+
+ all_target_pbrs = []
+ for pbr_token in self.pbr_settings:
+ all_target_pbrs.append(target_imgs[pbr_token])
+ all_target_pbrs = torch.stack(all_target_pbrs, dim=0).transpose(1, 0)
+ all_target_pbrs = torch.cat(
+ (cond_imgs_tensor.unsqueeze(1).repeat(1, len(self.pbr_settings), 1, 1, 1, 1), all_target_pbrs), dim=2
+ )
+ all_target_pbrs = rearrange(all_target_pbrs, "b n_pbrs n c h w -> b c (n_pbrs h) (n w)")
+ gts = all_target_pbrs
+ outputs = torch.cat(outputs, dim=0).to(self.device)
+ images = torch.cat([gts, outputs], dim=-2)
+ self.validation_step_outputs.append(images)
+
+ @torch.no_grad()
+ def on_validation_epoch_end(self):
+ """Aggregates validation results at epoch end.
+
+ Gathers outputs from all GPUs (if distributed training),
+ creates a unified visualization grid, and saves to disk.
+ Only rank 0 process performs saving.
+ """
+ # [Result aggregation and visualization...]
+ # Key steps:
+ # 1. Gather validation outputs from all processes
+ # 2. Create image grid combining ground truths and predictions
+ # 3. Save visualization with step-numbered filename
+ # 4. Clear memory for next validation cycle
+
+ images = torch.cat(self.validation_step_outputs, dim=0)
+ all_images = self.all_gather(images)
+ all_images = rearrange(all_images, "r b c h w -> (r b) c h w")
+
+ if self.global_rank == 0:
+ grid = make_grid(all_images, nrow=8, normalize=True, value_range=(0, 1))
+ save_image(grid, os.path.join(self.logdir, "images_val", f"val_{self.global_step:07d}.png"))
+
+ self.validation_step_outputs.clear() # free memory
+
+ def configure_optimizers(self):
+ lr = self.learning_rate
+ optimizer = torch.optim.AdamW(self.unet.parameters(), lr=lr)
+
+ def lr_lambda(step):
+ warm_up_step = 1000
+ T_step = 9000
+ gamma = 0.9
+ min_lr = 0.1 if step >= warm_up_step else 0.0
+ max_lr = 1.0
+ normalized_step = step % (warm_up_step + T_step)
+ current_max_lr = max_lr * gamma ** (step // (warm_up_step + T_step))
+ if current_max_lr < min_lr:
+ current_max_lr = min_lr
+ if normalized_step < warm_up_step:
+ lr_step = min_lr + (normalized_step / warm_up_step) * (current_max_lr - min_lr)
+ else:
+ step_wc_wp = normalized_step - warm_up_step
+ ratio = step_wc_wp / T_step
+ lr_step = min_lr + 0.5 * (current_max_lr - min_lr) * (1 + math.cos(math.pi * ratio))
+ return lr_step
+
+ lr_scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda)
+
+ lr_scheduler_config = {
+ "scheduler": lr_scheduler,
+ "interval": "step",
+ "frequency": 1,
+ "monitor": "val_loss",
+ "strict": False,
+ "name": None,
+ }
+
+ return {"optimizer": optimizer, "lr_scheduler": lr_scheduler_config}
diff --git a/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/modules.py b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..55f0404a452ecd9d7bc20d84303c151c67d8bf8f
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/hunyuanpaintpbr/unet/modules.py
@@ -0,0 +1,1102 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import json
+import copy
+import numpy as np
+import torch
+import torch.nn as nn
+from einops import rearrange
+from typing import Any, Callable, Dict, List, Optional, Union, Tuple, Literal
+import diffusers
+from diffusers.utils import deprecate
+from diffusers import (
+ DDPMScheduler,
+ EulerAncestralDiscreteScheduler,
+ UNet2DConditionModel,
+)
+from diffusers.models import UNet2DConditionModel
+from diffusers.models.attention_processor import Attention, AttnProcessor
+from diffusers.models.transformers.transformer_2d import BasicTransformerBlock
+from .attn_processor import SelfAttnProcessor2_0, RefAttnProcessor2_0, PoseRoPEAttnProcessor2_0
+
+from transformers import AutoImageProcessor, AutoModel
+
+
+class Dino_v2(nn.Module):
+
+ """Wrapper for DINOv2 vision transformer (frozen weights).
+
+ Provides feature extraction for reference images.
+
+ Args:
+ dino_v2_path: Custom path to DINOv2 model weights (uses default if None)
+ """
+
+
+ def __init__(self, dino_v2_path):
+ super(Dino_v2, self).__init__()
+ self.dino_processor = AutoImageProcessor.from_pretrained(dino_v2_path)
+ self.dino_v2 = AutoModel.from_pretrained(dino_v2_path)
+
+ for param in self.parameters():
+ param.requires_grad = False
+
+ self.dino_v2.eval()
+
+ def forward(self, images):
+
+ """Processes input images through DINOv2 ViT.
+
+ Handles both tensor input (B, N, C, H, W) and PIL image lists.
+ Extracts patch embeddings and flattens spatial dimensions.
+
+ Returns:
+ torch.Tensor: Feature vectors [B, N*(num_patches), feature_dim]
+ """
+
+ if isinstance(images, torch.Tensor):
+ batch_size = images.shape[0]
+ dino_proceesed_images = self.dino_processor(
+ images=rearrange(images, "b n c h w -> (b n) c h w"), return_tensors="pt", do_rescale=False
+ ).pixel_values
+ else:
+ batch_size = 1
+ dino_proceesed_images = self.dino_processor(images=images, return_tensors="pt").pixel_values
+ dino_proceesed_images = torch.stack(
+ [torch.from_numpy(np.array(image)) for image in dino_proceesed_images], dim=0
+ )
+ dino_param = next(self.dino_v2.parameters())
+ dino_proceesed_images = dino_proceesed_images.to(dino_param)
+ dino_hidden_states = self.dino_v2(dino_proceesed_images)[0]
+ dino_hidden_states = rearrange(dino_hidden_states.to(dino_param), "(b n) l c -> b (n l) c", b=batch_size)
+
+ return dino_hidden_states
+
+
+def _chunked_feed_forward(ff: nn.Module, hidden_states: torch.Tensor, chunk_dim: int, chunk_size: int):
+ # "feed_forward_chunk_size" can be used to save memory
+
+ """Memory-efficient feedforward execution via chunking.
+
+ Divides input along specified dimension for sequential processing.
+
+ Args:
+ ff: Feedforward module to apply
+ hidden_states: Input tensor
+ chunk_dim: Dimension to split
+ chunk_size: Size of each chunk
+
+ Returns:
+ torch.Tensor: Reassembled output tensor
+ """
+
+ if hidden_states.shape[chunk_dim] % chunk_size != 0:
+ raise ValueError(
+ f"`hidden_states` dimension to be chunked: {hidden_states.shape[chunk_dim]}"
+ f"has to be divisible by chunk size: {chunk_size}."
+ "Make sure to set an appropriate `chunk_size` when calling `unet.enable_forward_chunking`."
+ )
+
+ num_chunks = hidden_states.shape[chunk_dim] // chunk_size
+ ff_output = torch.cat(
+ [ff(hid_slice) for hid_slice in hidden_states.chunk(num_chunks, dim=chunk_dim)],
+ dim=chunk_dim,
+ )
+ return ff_output
+
+
+@torch.no_grad()
+def compute_voxel_grid_mask(position, grid_resolution=8):
+
+ """Generates view-to-view attention mask based on 3D position similarity.
+
+ Uses voxel grid downsampling to determine spatially adjacent regions.
+ Mask indicates where features should interact across different views.
+
+ Args:
+ position: Position maps [B, N, 3, H, W] (normalized 0-1)
+ grid_resolution: Spatial reduction factor
+
+ Returns:
+ torch.Tensor: Attention mask [B, N*grid_res**2, N*grid_res**2]
+ """
+
+ position = position.half()
+ B, N, _, H, W = position.shape
+ assert H % grid_resolution == 0 and W % grid_resolution == 0
+
+ valid_mask = (position != 1).all(dim=2, keepdim=True)
+ valid_mask = valid_mask.expand_as(position)
+ position[valid_mask == False] = 0
+
+ position = rearrange(
+ position,
+ "b n c (num_h grid_h) (num_w grid_w) -> b n num_h num_w c grid_h grid_w",
+ num_h=grid_resolution,
+ num_w=grid_resolution,
+ )
+ valid_mask = rearrange(
+ valid_mask,
+ "b n c (num_h grid_h) (num_w grid_w) -> b n num_h num_w c grid_h grid_w",
+ num_h=grid_resolution,
+ num_w=grid_resolution,
+ )
+
+ grid_position = position.sum(dim=(-2, -1))
+ count_masked = valid_mask.sum(dim=(-2, -1))
+
+ grid_position = grid_position / count_masked.clamp(min=1)
+ grid_position[count_masked < 5] = 0
+
+ grid_position = grid_position.permute(0, 1, 4, 2, 3)
+ grid_position = rearrange(grid_position, "b n c h w -> b n (h w) c")
+
+ grid_position_expanded_1 = grid_position.unsqueeze(2).unsqueeze(4) # 形状变为 B, N, 1, L, 1, 3
+ grid_position_expanded_2 = grid_position.unsqueeze(1).unsqueeze(3) # 形状变为 B, 1, N, 1, L, 3
+
+ # 计算欧氏距离
+ distances = torch.norm(grid_position_expanded_1 - grid_position_expanded_2, dim=-1) # 形状为 B, N, N, L, L
+
+ weights = distances
+ grid_distance = 1.73 / grid_resolution
+ weights = weights < grid_distance
+
+ return weights
+
+
+def compute_multi_resolution_mask(position_maps, grid_resolutions=[32, 16, 8]):
+
+ """Generates attention masks at multiple spatial resolutions.
+
+ Creates pyramid of position-based masks for hierarchical attention.
+
+ Args:
+ position_maps: Position maps [B, N, 3, H, W]
+ grid_resolutions: List of downsampling factors
+
+ Returns:
+ dict: Resolution-specific masks keyed by flattened dimension size
+ """
+
+ position_attn_mask = {}
+ with torch.no_grad():
+ for grid_resolution in grid_resolutions:
+ position_mask = compute_voxel_grid_mask(position_maps, grid_resolution)
+ position_mask = rearrange(position_mask, "b ni nj li lj -> b (ni li) (nj lj)")
+ position_attn_mask[position_mask.shape[1]] = position_mask
+ return position_attn_mask
+
+
+@torch.no_grad()
+def compute_discrete_voxel_indice(position, grid_resolution=8, voxel_resolution=128):
+
+ """Quantizes position maps to discrete voxel indices.
+
+ Creates sparse 3D coordinate representations for efficient hashing.
+
+ Args:
+ position: Position maps [B, N, 3, H, W]
+ grid_resolution: Spatial downsampling factor
+ voxel_resolution: Quantization resolution
+
+ Returns:
+ torch.Tensor: Voxel indices [B, N, grid_res, grid_res, 3]
+ """
+
+ position = position.half()
+ B, N, _, H, W = position.shape
+ assert H % grid_resolution == 0 and W % grid_resolution == 0
+
+ valid_mask = (position != 1).all(dim=2, keepdim=True)
+ valid_mask = valid_mask.expand_as(position)
+ position[valid_mask == False] = 0
+
+ position = rearrange(
+ position,
+ "b n c (num_h grid_h) (num_w grid_w) -> b n num_h num_w c grid_h grid_w",
+ num_h=grid_resolution,
+ num_w=grid_resolution,
+ )
+ valid_mask = rearrange(
+ valid_mask,
+ "b n c (num_h grid_h) (num_w grid_w) -> b n num_h num_w c grid_h grid_w",
+ num_h=grid_resolution,
+ num_w=grid_resolution,
+ )
+
+ grid_position = position.sum(dim=(-2, -1))
+ count_masked = valid_mask.sum(dim=(-2, -1))
+
+ grid_position = grid_position / count_masked.clamp(min=1)
+ voxel_mask_thres = (H // grid_resolution) * (W // grid_resolution) // (4 * 4)
+ grid_position[count_masked < voxel_mask_thres] = 0
+
+ grid_position = grid_position.permute(0, 1, 4, 2, 3).clamp(0, 1) # B N C H W
+ voxel_indices = grid_position * (voxel_resolution - 1)
+ voxel_indices = torch.round(voxel_indices).long()
+ return voxel_indices
+
+
+def calc_multires_voxel_idxs(position_maps, grid_resolutions=[64, 32, 16, 8], voxel_resolutions=[512, 256, 128, 64]):
+
+ """Generates multi-resolution voxel indices for position encoding.
+
+ Creates pyramid of quantized position representations.
+
+ Args:
+ position_maps: Input position maps
+ grid_resolutions: Spatial resolution levels
+ voxel_resolutions: Quantization levels
+
+ Returns:
+ dict: Voxel indices keyed by flattened dimension size, with resolution metadata
+ """
+
+ voxel_indices = {}
+ with torch.no_grad():
+ for grid_resolution, voxel_resolution in zip(grid_resolutions, voxel_resolutions):
+ voxel_indice = compute_discrete_voxel_indice(position_maps, grid_resolution, voxel_resolution)
+ voxel_indice = rearrange(voxel_indice, "b n c h w -> b (n h w) c")
+ voxel_indices[voxel_indice.shape[1]] = {"voxel_indices": voxel_indice, "voxel_resolution": voxel_resolution}
+ return voxel_indices
+
+
+class Basic2p5DTransformerBlock(torch.nn.Module):
+
+
+ """Enhanced transformer block for multiview 2.5D image generation.
+
+ Extends standard transformer blocks with:
+ - Material-specific attention (MDA)
+ - Multiview attention (MA)
+ - Reference attention (RA)
+ - DINO feature integration
+
+ Args:
+ transformer: Base transformer block
+ layer_name: Identifier for layer
+ use_ma: Enable multiview attention
+ use_ra: Enable reference attention
+ use_mda: Enable material-aware attention
+ use_dino: Enable DINO feature integration
+ pbr_setting: List of PBR materials
+ """
+
+ def __init__(
+ self,
+ transformer: BasicTransformerBlock,
+ layer_name,
+ use_ma=True,
+ use_ra=True,
+ use_mda=True,
+ use_dino=True,
+ pbr_setting=None,
+ ) -> None:
+
+ """
+ Initialization:
+ 1. Material-Dimension Attention (MDA):
+ - Processes each PBR material with separate projection weights
+ - Uses custom SelfAttnProcessor2_0 with material awareness
+
+ 2. Multiview Attention (MA):
+ - Adds cross-view attention with PoseRoPE
+ - Initialized as zero-initialized residual pathway
+
+ 3. Reference Attention (RA):
+ - Conditions on reference view features
+ - Uses RefAttnProcessor2_0 for material-specific conditioning
+
+ 4. DINO Attention:
+ - Incorporates DINO-ViT features
+ - Initialized as zero-initialized residual pathway
+ """
+
+ super().__init__()
+ self.transformer = transformer
+ self.layer_name = layer_name
+ self.use_ma = use_ma
+ self.use_ra = use_ra
+ self.use_mda = use_mda
+ self.use_dino = use_dino
+ self.pbr_setting = pbr_setting
+
+ if self.use_mda:
+ self.attn1.set_processor(
+ SelfAttnProcessor2_0(
+ query_dim=self.dim,
+ heads=self.num_attention_heads,
+ dim_head=self.attention_head_dim,
+ dropout=self.dropout,
+ bias=self.attention_bias,
+ cross_attention_dim=None,
+ upcast_attention=self.attn1.upcast_attention,
+ out_bias=True,
+ pbr_setting=self.pbr_setting,
+ )
+ )
+
+ # multiview attn
+ if self.use_ma:
+ self.attn_multiview = Attention(
+ query_dim=self.dim,
+ heads=self.num_attention_heads,
+ dim_head=self.attention_head_dim,
+ dropout=self.dropout,
+ bias=self.attention_bias,
+ cross_attention_dim=None,
+ upcast_attention=self.attn1.upcast_attention,
+ out_bias=True,
+ processor=PoseRoPEAttnProcessor2_0(),
+ )
+
+ # ref attn
+ if self.use_ra:
+ self.attn_refview = Attention(
+ query_dim=self.dim,
+ heads=self.num_attention_heads,
+ dim_head=self.attention_head_dim,
+ dropout=self.dropout,
+ bias=self.attention_bias,
+ cross_attention_dim=None,
+ upcast_attention=self.attn1.upcast_attention,
+ out_bias=True,
+ processor=RefAttnProcessor2_0(
+ query_dim=self.dim,
+ heads=self.num_attention_heads,
+ dim_head=self.attention_head_dim,
+ dropout=self.dropout,
+ bias=self.attention_bias,
+ cross_attention_dim=None,
+ upcast_attention=self.attn1.upcast_attention,
+ out_bias=True,
+ pbr_setting=self.pbr_setting,
+ ),
+ )
+
+ # dino attn
+ if self.use_dino:
+ self.attn_dino = Attention(
+ query_dim=self.dim,
+ heads=self.num_attention_heads,
+ dim_head=self.attention_head_dim,
+ dropout=self.dropout,
+ bias=self.attention_bias,
+ cross_attention_dim=self.cross_attention_dim,
+ upcast_attention=self.attn2.upcast_attention,
+ out_bias=True,
+ )
+
+ self._initialize_attn_weights()
+
+ def _initialize_attn_weights(self):
+
+ """Initializes specialized attention heads with base weights.
+
+ Uses weight sharing strategy:
+ - Copies base transformer weights to specialized heads
+ - Initializes newly-added parameters to zero
+ """
+
+ if self.use_mda:
+ for token in self.pbr_setting:
+ if token == "albedo":
+ continue
+ getattr(self.attn1.processor, f"to_q_{token}").load_state_dict(self.attn1.to_q.state_dict())
+ getattr(self.attn1.processor, f"to_k_{token}").load_state_dict(self.attn1.to_k.state_dict())
+ getattr(self.attn1.processor, f"to_v_{token}").load_state_dict(self.attn1.to_v.state_dict())
+ getattr(self.attn1.processor, f"to_out_{token}").load_state_dict(self.attn1.to_out.state_dict())
+
+ if self.use_ma:
+ self.attn_multiview.load_state_dict(self.attn1.state_dict(), strict=False)
+ with torch.no_grad():
+ for layer in self.attn_multiview.to_out:
+ for param in layer.parameters():
+ param.zero_()
+
+ if self.use_ra:
+ self.attn_refview.load_state_dict(self.attn1.state_dict(), strict=False)
+ for token in self.pbr_setting:
+ if token == "albedo":
+ continue
+ getattr(self.attn_refview.processor, f"to_v_{token}").load_state_dict(
+ self.attn_refview.to_q.state_dict()
+ )
+ getattr(self.attn_refview.processor, f"to_out_{token}").load_state_dict(
+ self.attn_refview.to_out.state_dict()
+ )
+ with torch.no_grad():
+ for layer in self.attn_refview.to_out:
+ for param in layer.parameters():
+ param.zero_()
+ for token in self.pbr_setting:
+ if token == "albedo":
+ continue
+ for layer in getattr(self.attn_refview.processor, f"to_out_{token}"):
+ for param in layer.parameters():
+ param.zero_()
+
+ if self.use_dino:
+ self.attn_dino.load_state_dict(self.attn2.state_dict(), strict=False)
+ with torch.no_grad():
+ for layer in self.attn_dino.to_out:
+ for param in layer.parameters():
+ param.zero_()
+
+ if self.use_dino:
+ self.attn_dino.load_state_dict(self.attn2.state_dict(), strict=False)
+ with torch.no_grad():
+ for layer in self.attn_dino.to_out:
+ for param in layer.parameters():
+ param.zero_()
+
+ def __getattr__(self, name: str):
+ try:
+ return super().__getattr__(name)
+ except AttributeError:
+ return getattr(self.transformer, name)
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ encoder_attention_mask: Optional[torch.Tensor] = None,
+ timestep: Optional[torch.LongTensor] = None,
+ cross_attention_kwargs: Dict[str, Any] = None,
+ class_labels: Optional[torch.LongTensor] = None,
+ added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None,
+ ) -> torch.Tensor:
+
+ """Forward pass with multi-mechanism attention.
+
+ Processing stages:
+ 1. Material-aware self-attention (MDA)
+ 2. Reference attention (RA)
+ 3. Multiview attention (MA) with position-aware attention
+ 4. Text conditioning (base attention)
+ 5. DINO feature conditioning (optional)
+ 6. Position-aware conditioning
+ 7. Feed-forward network
+
+ Args:
+ hidden_states: Input features [B * N_materials * N_views, Seq_len, Feat_dim]
+ See base transformer for other parameters
+
+ Returns:
+ torch.Tensor: Output features
+ """
+ # [Full multi-mechanism processing pipeline...]
+ # Key processing stages:
+ # 1. Material-aware self-attention (handles albedo/mr separation)
+ # 2. Reference attention (conditioned on reference features)
+ # 3. View-to-view attention with geometric constraints
+ # 4. Text-to-image cross-attention
+ # 5. DINO feature fusion (when enabled)
+ # 6. Positional conditioning (RoPE-style)
+ # 7. Feed-forward network with conditional normalization
+
+ # Notice that normalization is always applied before the real computation in the following blocks.
+ # 0. Self-Attention
+ batch_size = hidden_states.shape[0]
+
+ cross_attention_kwargs = cross_attention_kwargs.copy() if cross_attention_kwargs is not None else {}
+ num_in_batch = cross_attention_kwargs.pop("num_in_batch", 1)
+ mode = cross_attention_kwargs.pop("mode", None)
+ mva_scale = cross_attention_kwargs.pop("mva_scale", 1.0)
+ ref_scale = cross_attention_kwargs.pop("ref_scale", 1.0)
+ condition_embed_dict = cross_attention_kwargs.pop("condition_embed_dict", None)
+ dino_hidden_states = cross_attention_kwargs.pop("dino_hidden_states", None)
+ position_voxel_indices = cross_attention_kwargs.pop("position_voxel_indices", None)
+ N_pbr = len(self.pbr_setting) if self.pbr_setting is not None else 1
+
+ if self.norm_type == "ada_norm":
+ norm_hidden_states = self.norm1(hidden_states, timestep)
+ elif self.norm_type == "ada_norm_zero":
+ norm_hidden_states, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.norm1(
+ hidden_states, timestep, class_labels, hidden_dtype=hidden_states.dtype
+ )
+ elif self.norm_type in ["layer_norm", "layer_norm_i2vgen"]:
+ norm_hidden_states = self.norm1(hidden_states)
+ elif self.norm_type == "ada_norm_continuous":
+ norm_hidden_states = self.norm1(hidden_states, added_cond_kwargs["pooled_text_emb"])
+ elif self.norm_type == "ada_norm_single":
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
+ self.scale_shift_table[None] + timestep.reshape(batch_size, 6, -1)
+ ).chunk(6, dim=1)
+ norm_hidden_states = self.norm1(hidden_states)
+ norm_hidden_states = norm_hidden_states * (1 + scale_msa) + shift_msa
+ else:
+ raise ValueError("Incorrect norm used")
+
+ if self.pos_embed is not None:
+ norm_hidden_states = self.pos_embed(norm_hidden_states)
+
+ # 1. Prepare GLIGEN inputs
+ cross_attention_kwargs = cross_attention_kwargs.copy() if cross_attention_kwargs is not None else {}
+ gligen_kwargs = cross_attention_kwargs.pop("gligen", None)
+
+ if self.use_mda:
+ mda_norm_hidden_states = rearrange(
+ norm_hidden_states, "(b n_pbr n) l c -> b n_pbr n l c", n=num_in_batch, n_pbr=N_pbr
+ )
+ attn_output = self.attn1(
+ mda_norm_hidden_states,
+ encoder_hidden_states=encoder_hidden_states if self.only_cross_attention else None,
+ attention_mask=attention_mask,
+ **cross_attention_kwargs,
+ )
+ attn_output = rearrange(attn_output, "b n_pbr n l c -> (b n_pbr n) l c")
+ else:
+ attn_output = self.attn1(
+ norm_hidden_states,
+ encoder_hidden_states=encoder_hidden_states if self.only_cross_attention else None,
+ attention_mask=attention_mask,
+ **cross_attention_kwargs,
+ )
+
+ if self.norm_type == "ada_norm_zero":
+ attn_output = gate_msa.unsqueeze(1) * attn_output
+ elif self.norm_type == "ada_norm_single":
+ attn_output = gate_msa * attn_output
+
+ hidden_states = attn_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ # 1.2 Reference Attention
+ if "w" in mode:
+ condition_embed_dict[self.layer_name] = rearrange(
+ norm_hidden_states, "(b n) l c -> b (n l) c", n=num_in_batch
+ ) # B, (N L), C
+
+ if "r" in mode and self.use_ra:
+ condition_embed = condition_embed_dict[self.layer_name]
+
+ #! Only using albedo features for reference attention
+ ref_norm_hidden_states = rearrange(
+ norm_hidden_states, "(b n_pbr n) l c -> b n_pbr (n l) c", n=num_in_batch, n_pbr=N_pbr
+ )[:, 0, ...]
+
+ attn_output = self.attn_refview(
+ ref_norm_hidden_states,
+ encoder_hidden_states=condition_embed,
+ attention_mask=None,
+ **cross_attention_kwargs,
+ ) # b (n l) c
+ attn_output = rearrange(attn_output, "b n_pbr (n l) c -> (b n_pbr n) l c", n=num_in_batch, n_pbr=N_pbr)
+
+ ref_scale_timing = ref_scale
+ if isinstance(ref_scale, torch.Tensor):
+ ref_scale_timing = ref_scale.unsqueeze(1).repeat(1, num_in_batch * N_pbr).view(-1)
+ for _ in range(attn_output.ndim - 1):
+ ref_scale_timing = ref_scale_timing.unsqueeze(-1)
+ hidden_states = ref_scale_timing * attn_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ # 1.3 Multiview Attention
+ if num_in_batch > 1 and self.use_ma:
+ multivew_hidden_states = rearrange(
+ norm_hidden_states, "(b n_pbr n) l c -> (b n_pbr) (n l) c", n_pbr=N_pbr, n=num_in_batch
+ )
+ position_indices = None
+ if position_voxel_indices is not None:
+ if multivew_hidden_states.shape[1] in position_voxel_indices:
+ position_indices = position_voxel_indices[multivew_hidden_states.shape[1]]
+
+ attn_output = self.attn_multiview(
+ multivew_hidden_states,
+ encoder_hidden_states=multivew_hidden_states,
+ position_indices=position_indices,
+ n_pbrs=N_pbr,
+ **cross_attention_kwargs,
+ )
+
+ attn_output = rearrange(attn_output, "(b n_pbr) (n l) c -> (b n_pbr n) l c", n_pbr=N_pbr, n=num_in_batch)
+
+ hidden_states = mva_scale * attn_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ # 1.2 GLIGEN Control
+ if gligen_kwargs is not None:
+ hidden_states = self.fuser(hidden_states, gligen_kwargs["objs"])
+
+ # 3. Cross-Attention
+ if self.attn2 is not None:
+ if self.norm_type == "ada_norm":
+ norm_hidden_states = self.norm2(hidden_states, timestep)
+ elif self.norm_type in ["ada_norm_zero", "layer_norm", "layer_norm_i2vgen"]:
+ norm_hidden_states = self.norm2(hidden_states)
+ elif self.norm_type == "ada_norm_single":
+ # For PixArt norm2 isn't applied here:
+ # https://github.com/PixArt-alpha/PixArt-alpha/blob/0f55e922376d8b797edd44d25d0e7464b260dcab/diffusion/model/nets/PixArtMS.py#L70C1-L76C103
+ norm_hidden_states = hidden_states
+ elif self.norm_type == "ada_norm_continuous":
+ norm_hidden_states = self.norm2(hidden_states, added_cond_kwargs["pooled_text_emb"])
+ else:
+ raise ValueError("Incorrect norm")
+
+ if self.pos_embed is not None and self.norm_type != "ada_norm_single":
+ norm_hidden_states = self.pos_embed(norm_hidden_states)
+
+ attn_output = self.attn2(
+ norm_hidden_states,
+ encoder_hidden_states=encoder_hidden_states,
+ attention_mask=encoder_attention_mask,
+ **cross_attention_kwargs,
+ )
+ hidden_states = attn_output + hidden_states
+
+ # dino attn
+ if self.use_dino:
+ dino_hidden_states = dino_hidden_states.unsqueeze(1).repeat(1, N_pbr * num_in_batch, 1, 1)
+ dino_hidden_states = rearrange(dino_hidden_states, "b n l c -> (b n) l c")
+ attn_output = self.attn_dino(
+ norm_hidden_states,
+ encoder_hidden_states=dino_hidden_states,
+ attention_mask=None,
+ **cross_attention_kwargs,
+ )
+
+ hidden_states = attn_output + hidden_states
+
+ # 4. Feed-forward
+ # i2vgen doesn't have this norm 🤷♂️
+ if self.norm_type == "ada_norm_continuous":
+ norm_hidden_states = self.norm3(hidden_states, added_cond_kwargs["pooled_text_emb"])
+ elif not self.norm_type == "ada_norm_single":
+ norm_hidden_states = self.norm3(hidden_states)
+
+ if self.norm_type == "ada_norm_zero":
+ norm_hidden_states = norm_hidden_states * (1 + scale_mlp[:, None]) + shift_mlp[:, None]
+
+ if self.norm_type == "ada_norm_single":
+ norm_hidden_states = self.norm2(hidden_states)
+ norm_hidden_states = norm_hidden_states * (1 + scale_mlp) + shift_mlp
+
+ if self._chunk_size is not None:
+ # "feed_forward_chunk_size" can be used to save memory
+ ff_output = _chunked_feed_forward(self.ff, norm_hidden_states, self._chunk_dim, self._chunk_size)
+ else:
+ ff_output = self.ff(norm_hidden_states)
+
+ if self.norm_type == "ada_norm_zero":
+ ff_output = gate_mlp.unsqueeze(1) * ff_output
+ elif self.norm_type == "ada_norm_single":
+ ff_output = gate_mlp * ff_output
+
+ hidden_states = ff_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ return hidden_states
+
+
+class ImageProjModel(torch.nn.Module):
+
+ """Projects image embeddings into cross-attention space.
+
+ Transforms CLIP embeddings into additional context tokens for conditioning.
+
+ Args:
+ cross_attention_dim: Dimension of attention space
+ clip_embeddings_dim: Dimension of input CLIP embeddings
+ clip_extra_context_tokens: Number of context tokens to generate
+ """
+
+ def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4):
+ super().__init__()
+
+ self.generator = None
+ self.cross_attention_dim = cross_attention_dim
+ self.clip_extra_context_tokens = clip_extra_context_tokens
+ self.proj = torch.nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim)
+ self.norm = torch.nn.LayerNorm(cross_attention_dim)
+
+ def forward(self, image_embeds):
+
+ """Projects image embeddings to cross-attention context tokens.
+
+ Args:
+ image_embeds: Input embeddings [B, N, C] or [B, C]
+
+ Returns:
+ torch.Tensor: Context tokens [B, N*clip_extra_context_tokens, cross_attention_dim]
+ """
+
+ embeds = image_embeds
+ num_token = 1
+ if embeds.dim() == 3:
+ num_token = embeds.shape[1]
+ embeds = rearrange(embeds, "b n c -> (b n) c")
+
+ clip_extra_context_tokens = self.proj(embeds).reshape(
+ -1, self.clip_extra_context_tokens, self.cross_attention_dim
+ )
+ clip_extra_context_tokens = self.norm(clip_extra_context_tokens)
+
+ clip_extra_context_tokens = rearrange(clip_extra_context_tokens, "(b nt) n c -> b (nt n) c", nt=num_token)
+
+ return clip_extra_context_tokens
+
+
+class UNet2p5DConditionModel(torch.nn.Module):
+
+ """2.5D UNet extension for multiview PBR generation.
+
+ Enhances standard 2D UNet with:
+ - Multiview attention mechanisms
+ - Material-aware processing
+ - Position-aware conditioning
+ - Dual-stream reference processing
+
+ Args:
+ unet: Base 2D UNet model
+ train_sched: Training scheduler (DDPM)
+ val_sched: Validation scheduler (EulerAncestral)
+ """
+
+ def __init__(
+ self,
+ unet: UNet2DConditionModel,
+ train_sched: DDPMScheduler = None,
+ val_sched: EulerAncestralDiscreteScheduler = None,
+ ) -> None:
+ super().__init__()
+ self.unet = unet
+ self.train_sched = train_sched
+ self.val_sched = val_sched
+
+ self.use_ma = True
+ self.use_ra = True
+ self.use_mda = True
+ self.use_dino = True
+ self.use_position_rope = True
+ self.use_learned_text_clip = True
+ self.use_dual_stream = True
+ self.pbr_setting = ["albedo", "mr"]
+ self.pbr_token_channels = 77
+
+ if self.use_dual_stream and self.use_ra:
+ self.unet_dual = copy.deepcopy(unet)
+ self.init_attention(self.unet_dual)
+
+ self.init_attention(
+ self.unet,
+ use_ma=self.use_ma,
+ use_ra=self.use_ra,
+ use_dino=self.use_dino,
+ use_mda=self.use_mda,
+ pbr_setting=self.pbr_setting,
+ )
+ self.init_condition(use_dino=self.use_dino)
+
+ @staticmethod
+ def from_pretrained(pretrained_model_name_or_path, **kwargs):
+ torch_dtype = kwargs.pop("torch_dtype", torch.float32)
+ config_path = os.path.join(pretrained_model_name_or_path, "config.json")
+ unet_ckpt_path = os.path.join(pretrained_model_name_or_path, "diffusion_pytorch_model.bin")
+ with open(config_path, "r", encoding="utf-8") as file:
+ config = json.load(file)
+ unet = UNet2DConditionModel(**config)
+ unet_2p5d = UNet2p5DConditionModel(unet)
+ unet_2p5d.unet.conv_in = torch.nn.Conv2d(
+ 12,
+ unet.conv_in.out_channels,
+ kernel_size=unet.conv_in.kernel_size,
+ stride=unet.conv_in.stride,
+ padding=unet.conv_in.padding,
+ dilation=unet.conv_in.dilation,
+ groups=unet.conv_in.groups,
+ bias=unet.conv_in.bias is not None,
+ )
+ unet_ckpt = torch.load(unet_ckpt_path, map_location="cpu", weights_only=True)
+ unet_2p5d.load_state_dict(unet_ckpt, strict=True)
+ unet_2p5d = unet_2p5d.to(torch_dtype)
+ return unet_2p5d
+
+ def init_condition(self, use_dino):
+
+ """Initializes conditioning mechanisms for multiview PBR generation.
+
+ Sets up:
+ 1. Learned text embeddings: Material-specific tokens (albedo, mr) initialized to zeros
+ 2. DINO projector: Model to process DINO-ViT features for cross-attention
+
+ Args:
+ use_dino: Flag to enable DINO feature integration
+ """
+
+ if self.use_learned_text_clip:
+ for token in self.pbr_setting:
+ self.unet.register_parameter(
+ f"learned_text_clip_{token}", nn.Parameter(torch.zeros(self.pbr_token_channels, 1024))
+ )
+ self.unet.learned_text_clip_ref = nn.Parameter(torch.zeros(self.pbr_token_channels, 1024))
+
+ if use_dino:
+ self.unet.image_proj_model_dino = ImageProjModel(
+ cross_attention_dim=self.unet.config.cross_attention_dim,
+ clip_embeddings_dim=1536,
+ clip_extra_context_tokens=4,
+ )
+
+ def init_attention(self, unet, use_ma=False, use_ra=False, use_mda=False, use_dino=False, pbr_setting=None):
+
+ """Recursively replaces standard transformers with enhanced 2.5D blocks.
+
+ Processes UNet architecture:
+ 1. Downsampling blocks: Replaces transformers in attention layers
+ 2. Middle block: Upgrades central transformers
+ 3. Upsampling blocks: Modifies decoder transformers
+
+ Args:
+ unet: UNet model to enhance
+ use_ma: Enable multiview attention
+ use_ra: Enable reference attention
+ use_mda: Enable material-specific attention
+ use_dino: Enable DINO feature integration
+ pbr_setting: List of PBR materials
+ """
+
+ for down_block_i, down_block in enumerate(unet.down_blocks):
+ if hasattr(down_block, "has_cross_attention") and down_block.has_cross_attention:
+ for attn_i, attn in enumerate(down_block.attentions):
+ for transformer_i, transformer in enumerate(attn.transformer_blocks):
+ if isinstance(transformer, BasicTransformerBlock):
+ attn.transformer_blocks[transformer_i] = Basic2p5DTransformerBlock(
+ transformer,
+ f"down_{down_block_i}_{attn_i}_{transformer_i}",
+ use_ma,
+ use_ra,
+ use_mda,
+ use_dino,
+ pbr_setting,
+ )
+
+ if hasattr(unet.mid_block, "has_cross_attention") and unet.mid_block.has_cross_attention:
+ for attn_i, attn in enumerate(unet.mid_block.attentions):
+ for transformer_i, transformer in enumerate(attn.transformer_blocks):
+ if isinstance(transformer, BasicTransformerBlock):
+ attn.transformer_blocks[transformer_i] = Basic2p5DTransformerBlock(
+ transformer, f"mid_{attn_i}_{transformer_i}", use_ma, use_ra, use_mda, use_dino, pbr_setting
+ )
+
+ for up_block_i, up_block in enumerate(unet.up_blocks):
+ if hasattr(up_block, "has_cross_attention") and up_block.has_cross_attention:
+ for attn_i, attn in enumerate(up_block.attentions):
+ for transformer_i, transformer in enumerate(attn.transformer_blocks):
+ if isinstance(transformer, BasicTransformerBlock):
+ attn.transformer_blocks[transformer_i] = Basic2p5DTransformerBlock(
+ transformer,
+ f"up_{up_block_i}_{attn_i}_{transformer_i}",
+ use_ma,
+ use_ra,
+ use_mda,
+ use_dino,
+ pbr_setting,
+ )
+
+ def __getattr__(self, name: str):
+ try:
+ return super().__getattr__(name)
+ except AttributeError:
+ return getattr(self.unet, name)
+
+ def forward(
+ self,
+ sample,
+ timestep,
+ encoder_hidden_states,
+ *args,
+ added_cond_kwargs=None,
+ cross_attention_kwargs=None,
+ down_intrablock_additional_residuals=None,
+ down_block_res_samples=None,
+ mid_block_res_sample=None,
+ **cached_condition,
+ ):
+
+ """Forward pass with multiview/material conditioning.
+
+ Key stages:
+ 1. Input preparation (concat normal/position maps)
+ 2. Reference feature extraction (dual-stream)
+ 3. Position encoding (voxel indices)
+ 4. DINO feature projection
+ 5. Main UNet processing with attention conditioning
+
+ Args:
+ sample: Input latents [B, N_pbr, N_gen, C, H, W]
+ cached_condition: Dictionary containing:
+ - embeds_normal: Normal map embeddings
+ - embeds_position: Position map embeddings
+ - ref_latents: Reference image latents
+ - dino_hidden_states: DINO features
+ - position_maps: 3D position maps
+ - mva_scale: Multiview attention scale
+ - ref_scale: Reference attention scale
+
+ Returns:
+ torch.Tensor: Output features
+ """
+
+ B, N_pbr, N_gen, _, H, W = sample.shape
+ assert H == W
+
+ if "cache" not in cached_condition:
+ cached_condition["cache"] = {}
+
+ sample = [sample]
+ if "embeds_normal" in cached_condition:
+ sample.append(cached_condition["embeds_normal"].unsqueeze(1).repeat(1, N_pbr, 1, 1, 1, 1))
+ if "embeds_position" in cached_condition:
+ sample.append(cached_condition["embeds_position"].unsqueeze(1).repeat(1, N_pbr, 1, 1, 1, 1))
+ sample = torch.cat(sample, dim=-3)
+
+ sample = rearrange(sample, "b n_pbr n c h w -> (b n_pbr n) c h w")
+
+ encoder_hidden_states_gen = encoder_hidden_states.unsqueeze(-3).repeat(1, 1, N_gen, 1, 1)
+ encoder_hidden_states_gen = rearrange(encoder_hidden_states_gen, "b n_pbr n l c -> (b n_pbr n) l c")
+
+ if added_cond_kwargs is not None:
+ text_embeds_gen = added_cond_kwargs["text_embeds"].unsqueeze(1).repeat(1, N_gen, 1)
+ text_embeds_gen = rearrange(text_embeds_gen, "b n c -> (b n) c")
+ time_ids_gen = added_cond_kwargs["time_ids"].unsqueeze(1).repeat(1, N_gen, 1)
+ time_ids_gen = rearrange(time_ids_gen, "b n c -> (b n) c")
+ added_cond_kwargs_gen = {"text_embeds": text_embeds_gen, "time_ids": time_ids_gen}
+ else:
+ added_cond_kwargs_gen = None
+
+ if self.use_position_rope:
+ if "position_voxel_indices" in cached_condition["cache"]:
+ position_voxel_indices = cached_condition["cache"]["position_voxel_indices"]
+ else:
+ if "position_maps" in cached_condition:
+ position_voxel_indices = calc_multires_voxel_idxs(
+ cached_condition["position_maps"],
+ grid_resolutions=[H, H // 2, H // 4, H // 8],
+ voxel_resolutions=[H * 8, H * 4, H * 2, H],
+ )
+ cached_condition["cache"]["position_voxel_indices"] = position_voxel_indices
+ else:
+ position_voxel_indices = None
+
+ if self.use_dino:
+ if "dino_hidden_states_proj" in cached_condition["cache"]:
+ dino_hidden_states = cached_condition["cache"]["dino_hidden_states_proj"]
+ else:
+ assert "dino_hidden_states" in cached_condition
+ dino_hidden_states = cached_condition["dino_hidden_states"]
+ dino_hidden_states = self.image_proj_model_dino(dino_hidden_states)
+ cached_condition["cache"]["dino_hidden_states_proj"] = dino_hidden_states
+ else:
+ dino_hidden_states = None
+
+ if self.use_ra:
+ if "condition_embed_dict" in cached_condition["cache"]:
+ condition_embed_dict = cached_condition["cache"]["condition_embed_dict"]
+ else:
+ condition_embed_dict = {}
+ ref_latents = cached_condition["ref_latents"]
+ N_ref = ref_latents.shape[1]
+
+ if not self.use_dual_stream:
+ ref_latents = [ref_latents]
+ if "embeds_normal" in cached_condition:
+ ref_latents.append(torch.zeros_like(ref_latents[0]))
+ if "embeds_position" in cached_condition:
+ ref_latents.append(torch.zeros_like(ref_latents[0]))
+ ref_latents = torch.cat(ref_latents, dim=2)
+
+ ref_latents = rearrange(ref_latents, "b n c h w -> (b n) c h w")
+
+ encoder_hidden_states_ref = self.unet.learned_text_clip_ref.repeat(B, N_ref, 1, 1)
+
+ encoder_hidden_states_ref = rearrange(encoder_hidden_states_ref, "b n l c -> (b n) l c")
+
+ if added_cond_kwargs is not None:
+ text_embeds_ref = added_cond_kwargs["text_embeds"].unsqueeze(1).repeat(1, N_ref, 1)
+ text_embeds_ref = rearrange(text_embeds_ref, "b n c -> (b n) c")
+ time_ids_ref = added_cond_kwargs["time_ids"].unsqueeze(1).repeat(1, N_ref, 1)
+ time_ids_ref = rearrange(time_ids_ref, "b n c -> (b n) c")
+ added_cond_kwargs_ref = {
+ "text_embeds": text_embeds_ref,
+ "time_ids": time_ids_ref,
+ }
+ else:
+ added_cond_kwargs_ref = None
+
+ noisy_ref_latents = ref_latents
+ timestep_ref = 0
+ if self.use_dual_stream:
+ unet_ref = self.unet_dual
+ else:
+ unet_ref = self.unet
+ unet_ref(
+ noisy_ref_latents,
+ timestep_ref,
+ encoder_hidden_states=encoder_hidden_states_ref,
+ class_labels=None,
+ added_cond_kwargs=added_cond_kwargs_ref,
+ # **kwargs
+ return_dict=False,
+ cross_attention_kwargs={
+ "mode": "w",
+ "num_in_batch": N_ref,
+ "condition_embed_dict": condition_embed_dict,
+ },
+ )
+ cached_condition["cache"]["condition_embed_dict"] = condition_embed_dict
+ else:
+ condition_embed_dict = None
+
+ mva_scale = cached_condition.get("mva_scale", 1.0)
+ ref_scale = cached_condition.get("ref_scale", 1.0)
+
+ return self.unet(
+ sample,
+ timestep,
+ encoder_hidden_states_gen,
+ *args,
+ class_labels=None,
+ added_cond_kwargs=added_cond_kwargs_gen,
+ down_intrablock_additional_residuals=(
+ [sample.to(dtype=self.unet.dtype) for sample in down_intrablock_additional_residuals]
+ if down_intrablock_additional_residuals is not None
+ else None
+ ),
+ down_block_additional_residuals=(
+ [sample.to(dtype=self.unet.dtype) for sample in down_block_res_samples]
+ if down_block_res_samples is not None
+ else None
+ ),
+ mid_block_additional_residual=(
+ mid_block_res_sample.to(dtype=self.unet.dtype) if mid_block_res_sample is not None else None
+ ),
+ return_dict=False,
+ cross_attention_kwargs={
+ "mode": "r",
+ "num_in_batch": N_gen,
+ "dino_hidden_states": dino_hidden_states,
+ "condition_embed_dict": condition_embed_dict,
+ "mva_scale": mva_scale,
+ "ref_scale": ref_scale,
+ "position_voxel_indices": position_voxel_indices,
+ },
+ )
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/__init__.py b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..319995298d19a223710c1a608c5152c80a813ece
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/__init__.py
@@ -0,0 +1,4 @@
+"""
+from .render import rasterize, interpolate
+"""
+from .render import *
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/render.py b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/render.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d06b5195ed18d3cb581ace9efc1c2cebed232eb
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/custom_rasterizer/render.py
@@ -0,0 +1,32 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import custom_rasterizer_kernel
+import torch
+
+
+def rasterize(pos, tri, resolution, clamp_depth=torch.zeros(0), use_depth_prior=0):
+ assert pos.device == tri.device
+ findices, barycentric = custom_rasterizer_kernel.rasterize_image(
+ pos[0], tri, clamp_depth, resolution[1], resolution[0], 1e-6, use_depth_prior
+ )
+ return findices, barycentric
+
+
+def interpolate(col, findices, barycentric, tri):
+ f = findices - 1 + (findices == 0)
+ vcol = col[0, tri.long()[f.long()]]
+ result = barycentric.view(*barycentric.shape, 1) * vcol
+ result = torch.sum(result, axis=-2)
+ return result.view(1, *result.shape)
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/__init__.py b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/grid_neighbor.cpp b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/grid_neighbor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f02bcba5afd45a524143d06c972acb87c393fe97
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/grid_neighbor.cpp
@@ -0,0 +1,574 @@
+#include "rasterizer.h"
+#include
+
+inline int pos2key(float* p, int resolution) {
+ int x = (p[0] * 0.5 + 0.5) * resolution;
+ int y = (p[1] * 0.5 + 0.5) * resolution;
+ int z = (p[2] * 0.5 + 0.5) * resolution;
+ return (x * resolution + y) * resolution + z;
+}
+
+inline void key2pos(int key, int resolution, float* p) {
+ int x = key / resolution / resolution;
+ int y = key / resolution % resolution;
+ int z = key % resolution;
+ p[0] = ((x + 0.5) / resolution - 0.5) * 2;
+ p[1] = ((y + 0.5) / resolution - 0.5) * 2;
+ p[2] = ((z + 0.5) / resolution - 0.5) * 2;
+}
+
+inline void key2cornerpos(int key, int resolution, float* p) {
+ int x = key / resolution / resolution;
+ int y = key / resolution % resolution;
+ int z = key % resolution;
+ p[0] = ((x + 0.75) / resolution - 0.5) * 2;
+ p[1] = ((y + 0.25) / resolution - 0.5) * 2;
+ p[2] = ((z + 0.75) / resolution - 0.5) * 2;
+}
+
+inline float* pos_ptr(int l, int i, int j, torch::Tensor t) {
+ float* pdata = t.data_ptr();
+ int height = t.size(1);
+ int width = t.size(2);
+ return &pdata[((l * height + i) * width + j) * 4];
+}
+
+struct Grid
+{
+ std::vector seq2oddcorner;
+ std::vector seq2evencorner;
+ std::vector seq2grid;
+ std::vector seq2normal;
+ std::vector seq2neighbor;
+ std::unordered_map grid2seq;
+ std::vector downsample_seq;
+ int num_origin_seq;
+ int resolution;
+ int stride;
+};
+
+inline void pos_from_seq(Grid& grid, int seq, float* p) {
+ auto k = grid.seq2grid[seq];
+ key2pos(k, grid.resolution, p);
+}
+
+inline int fetch_seq(Grid& grid, int l, int i, int j, torch::Tensor pdata) {
+ float* p = pos_ptr(l, i, j, pdata);
+ if (p[3] == 0)
+ return -1;
+ auto key = pos2key(p, grid.resolution);
+ int seq = grid.grid2seq[key];
+ return seq;
+}
+
+inline int fetch_last_seq(Grid& grid, int i, int j, torch::Tensor pdata) {
+ int num_layers = pdata.size(0);
+ int l = 0;
+ int idx = fetch_seq(grid, l, i, j, pdata);
+ while (l < num_layers - 1) {
+ l += 1;
+ int new_idx = fetch_seq(grid, l, i, j, pdata);
+ if (new_idx == -1)
+ break;
+ idx = new_idx;
+ }
+ return idx;
+}
+
+inline int fetch_nearest_seq(Grid& grid, int i, int j, int dim, float d, torch::Tensor pdata) {
+ float p[3];
+ float max_dist = 1e10;
+ int best_idx = -1;
+ int num_layers = pdata.size(0);
+ for (int l = 0; l < num_layers; ++l) {
+ int idx = fetch_seq(grid, l, i, j, pdata);
+ if (idx == -1)
+ break;
+ pos_from_seq(grid, idx, p);
+ float dist = std::abs(d - p[(dim + 2) % 3]);
+ if (dist < max_dist) {
+ max_dist = dist;
+ best_idx = idx;
+ }
+ }
+ return best_idx;
+}
+
+inline int fetch_nearest_seq_layer(Grid& grid, int i, int j, int dim, float d, torch::Tensor pdata) {
+ float p[3];
+ float max_dist = 1e10;
+ int best_layer = -1;
+ int num_layers = pdata.size(0);
+ for (int l = 0; l < num_layers; ++l) {
+ int idx = fetch_seq(grid, l, i, j, pdata);
+ if (idx == -1)
+ break;
+ pos_from_seq(grid, idx, p);
+ float dist = std::abs(d - p[(dim + 2) % 3]);
+ if (dist < max_dist) {
+ max_dist = dist;
+ best_layer = l;
+ }
+ }
+ return best_layer;
+}
+
+void FetchNeighbor(Grid& grid, int seq, float* pos, int dim, int boundary_info, std::vector& view_layer_positions,
+ int* output_indices)
+{
+ auto t = view_layer_positions[dim];
+ int height = t.size(1);
+ int width = t.size(2);
+ int top = 0;
+ int ci = 0;
+ int cj = 0;
+ if (dim == 0) {
+ ci = (pos[1]/2+0.5)*height;
+ cj = (pos[0]/2+0.5)*width;
+ }
+ else if (dim == 1) {
+ ci = (pos[1]/2+0.5)*height;
+ cj = (pos[2]/2+0.5)*width;
+ }
+ else {
+ ci = (-pos[2]/2+0.5)*height;
+ cj = (pos[0]/2+0.5)*width;
+ }
+ int stride = grid.stride;
+ for (int ni = ci + stride; ni >= ci - stride; ni -= stride) {
+ for (int nj = cj - stride; nj <= cj + stride; nj += stride) {
+ int idx = -1;
+ if (ni == ci && nj == cj)
+ idx = seq;
+ else if (!(ni < 0 || ni >= height || nj < 0 || nj >= width)) {
+ if (boundary_info == -1)
+ idx = fetch_seq(grid, 0, ni, nj, t);
+ else if (boundary_info == 1)
+ idx = fetch_last_seq(grid, ni, nj, t);
+ else
+ idx = fetch_nearest_seq(grid, ni, nj, dim, pos[(dim + 2) % 3], t);
+ }
+ output_indices[top] = idx;
+ top += 1;
+ }
+ }
+}
+
+void DownsampleGrid(Grid& src, Grid& tar)
+{
+ src.downsample_seq.resize(src.seq2grid.size(), -1);
+ tar.resolution = src.resolution / 2;
+ tar.stride = src.stride * 2;
+ float pos[3];
+ std::vector seq2normal_count;
+ for (int i = 0; i < src.seq2grid.size(); ++i) {
+ key2pos(src.seq2grid[i], src.resolution, pos);
+ int k = pos2key(pos, tar.resolution);
+ int s = seq2normal_count.size();
+ if (!tar.grid2seq.count(k)) {
+ tar.grid2seq[k] = tar.seq2grid.size();
+ tar.seq2grid.emplace_back(k);
+ seq2normal_count.emplace_back(0);
+ seq2normal_count.emplace_back(0);
+ seq2normal_count.emplace_back(0);
+ //tar.seq2normal.emplace_back(src.seq2normal[i]);
+ } else {
+ s = tar.grid2seq[k] * 3;
+ }
+ seq2normal_count[s + src.seq2normal[i]] += 1;
+ src.downsample_seq[i] = tar.grid2seq[k];
+ }
+ tar.seq2normal.resize(seq2normal_count.size() / 3);
+ for (int i = 0; i < seq2normal_count.size(); i += 3) {
+ int t = 0;
+ for (int j = 1; j < 3; ++j) {
+ if (seq2normal_count[i + j] > seq2normal_count[i + t])
+ t = j;
+ }
+ tar.seq2normal[i / 3] = t;
+ }
+}
+
+void NeighborGrid(Grid& grid, std::vector view_layer_positions, int v)
+{
+ grid.seq2evencorner.resize(grid.seq2grid.size(), 0);
+ grid.seq2oddcorner.resize(grid.seq2grid.size(), 0);
+ std::unordered_set visited_seq;
+ for (int vd = 0; vd < 3; ++vd) {
+ auto t = view_layer_positions[vd];
+ auto t0 = view_layer_positions[v];
+ int height = t.size(1);
+ int width = t.size(2);
+ int num_layers = t.size(0);
+ int num_view_layers = t0.size(0);
+ for (int i = 0; i < height; ++i) {
+ for (int j = 0; j < width; ++j) {
+ for (int l = 0; l < num_layers; ++l) {
+ int seq = fetch_seq(grid, l, i, j, t);
+ if (seq == -1)
+ break;
+ int dim = grid.seq2normal[seq];
+ if (dim != v)
+ continue;
+
+ float pos[3];
+ pos_from_seq(grid, seq, pos);
+
+ int ci = 0;
+ int cj = 0;
+ if (dim == 0) {
+ ci = (pos[1]/2+0.5)*height;
+ cj = (pos[0]/2+0.5)*width;
+ }
+ else if (dim == 1) {
+ ci = (pos[1]/2+0.5)*height;
+ cj = (pos[2]/2+0.5)*width;
+ }
+ else {
+ ci = (-pos[2]/2+0.5)*height;
+ cj = (pos[0]/2+0.5)*width;
+ }
+
+ if ((ci % (grid.stride * 2) < grid.stride) && (cj % (grid.stride * 2) >= grid.stride))
+ grid.seq2evencorner[seq] = 1;
+
+ if ((ci % (grid.stride * 2) >= grid.stride) && (cj % (grid.stride * 2) < grid.stride))
+ grid.seq2oddcorner[seq] = 1;
+
+ bool is_boundary = false;
+ if (vd == v) {
+ if (l == 0 || l == num_layers - 1)
+ is_boundary = true;
+ else {
+ int seq_new = fetch_seq(grid, l + 1, i, j, t);
+ if (seq_new == -1)
+ is_boundary = true;
+ }
+ }
+ int boundary_info = 0;
+ if (is_boundary && (l == 0))
+ boundary_info = -1;
+ else if (is_boundary)
+ boundary_info = 1;
+ if (visited_seq.count(seq))
+ continue;
+ visited_seq.insert(seq);
+
+ FetchNeighbor(grid, seq, pos, dim, boundary_info, view_layer_positions, &grid.seq2neighbor[seq * 9]);
+ }
+ }
+ }
+ }
+}
+
+void PadGrid(Grid& src, Grid& tar, std::vector& view_layer_positions) {
+ auto& downsample_seq = src.downsample_seq;
+ auto& seq2evencorner = src.seq2evencorner;
+ auto& seq2oddcorner = src.seq2oddcorner;
+ int indices[9];
+ std::vector mapped_even_corners(tar.seq2grid.size(), 0);
+ std::vector mapped_odd_corners(tar.seq2grid.size(), 0);
+ for (int i = 0; i < downsample_seq.size(); ++i) {
+ if (seq2evencorner[i] > 0) {
+ mapped_even_corners[downsample_seq[i]] = 1;
+ }
+ if (seq2oddcorner[i] > 0) {
+ mapped_odd_corners[downsample_seq[i]] = 1;
+ }
+ }
+ auto& tar_seq2normal = tar.seq2normal;
+ auto& tar_seq2grid = tar.seq2grid;
+ for (int i = 0; i < tar_seq2grid.size(); ++i) {
+ if (mapped_even_corners[i] == 1 && mapped_odd_corners[i] == 1)
+ continue;
+ auto k = tar_seq2grid[i];
+ float p[3];
+ key2cornerpos(k, tar.resolution, p);
+
+ int src_key = pos2key(p, src.resolution);
+ if (!src.grid2seq.count(src_key)) {
+ int seq = src.seq2grid.size();
+ src.grid2seq[src_key] = seq;
+ src.seq2evencorner.emplace_back((mapped_even_corners[i] == 0));
+ src.seq2oddcorner.emplace_back((mapped_odd_corners[i] == 0));
+ src.seq2grid.emplace_back(src_key);
+ src.seq2normal.emplace_back(tar_seq2normal[i]);
+ FetchNeighbor(src, seq, p, tar_seq2normal[i], 0, view_layer_positions, indices);
+ for (int j = 0; j < 9; ++j) {
+ src.seq2neighbor.emplace_back(indices[j]);
+ }
+ src.downsample_seq.emplace_back(i);
+ } else {
+ int seq = src.grid2seq[src_key];
+ if (mapped_even_corners[i] == 0)
+ src.seq2evencorner[seq] = 1;
+ if (mapped_odd_corners[i] == 0)
+ src.seq2oddcorner[seq] = 1;
+ }
+ }
+}
+
+std::vector> build_hierarchy(std::vector view_layer_positions,
+ std::vector view_layer_normals, int num_level, int resolution)
+{
+ if (view_layer_positions.size() != 3 || num_level < 1) {
+ printf("Alert! We require 3 layers and at least 1 level! (%d %d)\n", view_layer_positions.size(), num_level);
+ return {{},{},{},{}};
+ }
+
+ std::vector grids;
+ grids.resize(num_level);
+
+ std::vector seq2pos;
+ auto& seq2grid = grids[0].seq2grid;
+ auto& seq2normal = grids[0].seq2normal;
+ auto& grid2seq = grids[0].grid2seq;
+ grids[0].resolution = resolution;
+ grids[0].stride = 1;
+
+ auto int64_options = torch::TensorOptions().dtype(torch::kInt64).requires_grad(false);
+ auto float_options = torch::TensorOptions().dtype(torch::kFloat32).requires_grad(false);
+
+ for (int v = 0; v < 3; ++v) {
+ int num_layers = view_layer_positions[v].size(0);
+ int height = view_layer_positions[v].size(1);
+ int width = view_layer_positions[v].size(2);
+ float* data = view_layer_positions[v].data_ptr();
+ float* data_normal = view_layer_normals[v].data_ptr();
+ for (int l = 0; l < num_layers; ++l) {
+ for (int i = 0; i < height; ++i) {
+ for (int j = 0; j < width; ++j) {
+ float* p = &data[(i * width + j) * 4];
+ float* n = &data_normal[(i * width + j) * 3];
+ if (p[3] == 0)
+ continue;
+ auto k = pos2key(p, resolution);
+ if (!grid2seq.count(k)) {
+ int dim = 0;
+ for (int d = 0; d < 3; ++d) {
+ if (std::abs(n[d]) > std::abs(n[dim]))
+ dim = d;
+ }
+ dim = (dim + 1) % 3;
+ grid2seq[k] = seq2grid.size();
+ seq2grid.emplace_back(k);
+ seq2pos.push_back(p[0]);
+ seq2pos.push_back(p[1]);
+ seq2pos.push_back(p[2]);
+ seq2normal.emplace_back(dim);
+ }
+ }
+ }
+ data += (height * width * 4);
+ data_normal += (height * width * 3);
+ }
+ }
+
+ for (int i = 0; i < num_level - 1; ++i) {
+ DownsampleGrid(grids[i], grids[i + 1]);
+ }
+
+ for (int l = 0; l < num_level; ++l) {
+ grids[l].seq2neighbor.resize(grids[l].seq2grid.size() * 9, -1);
+ grids[l].num_origin_seq = grids[l].seq2grid.size();
+ for (int d = 0; d < 3; ++d) {
+ NeighborGrid(grids[l], view_layer_positions, d);
+ }
+ }
+
+ for (int i = num_level - 2; i >= 0; --i) {
+ PadGrid(grids[i], grids[i + 1], view_layer_positions);
+ }
+ for (int i = grids[0].num_origin_seq; i < grids[0].seq2grid.size(); ++i) {
+ int k = grids[0].seq2grid[i];
+ float p[3];
+ key2pos(k, grids[0].resolution, p);
+ seq2pos.push_back(p[0]);
+ seq2pos.push_back(p[1]);
+ seq2pos.push_back(p[2]);
+ }
+
+ std::vector texture_positions(2);
+ std::vector grid_neighbors(grids.size());
+ std::vector grid_downsamples(grids.size() - 1);
+ std::vector grid_evencorners(grids.size());
+ std::vector grid_oddcorners(grids.size());
+
+ texture_positions[0] = torch::zeros({seq2pos.size() / 3, 3}, float_options);
+ texture_positions[1] = torch::zeros({seq2pos.size() / 3}, float_options);
+ float* positions_out_ptr = texture_positions[0].data_ptr();
+ memcpy(positions_out_ptr, seq2pos.data(), sizeof(float) * seq2pos.size());
+ positions_out_ptr = texture_positions[1].data_ptr();
+ for (int i = 0; i < grids[0].seq2grid.size(); ++i) {
+ positions_out_ptr[i] = (i < grids[0].num_origin_seq);
+ }
+
+ for (int i = 0; i < grids.size(); ++i) {
+ grid_neighbors[i] = torch::zeros({grids[i].seq2grid.size(), 9}, int64_options);
+ long* nptr = grid_neighbors[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2neighbor.size(); ++j) {
+ nptr[j] = grids[i].seq2neighbor[j];
+ }
+
+ grid_evencorners[i] = torch::zeros({grids[i].seq2evencorner.size()}, int64_options);
+ grid_oddcorners[i] = torch::zeros({grids[i].seq2oddcorner.size()}, int64_options);
+ long* dptr = grid_evencorners[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2evencorner.size(); ++j) {
+ dptr[j] = grids[i].seq2evencorner[j];
+ }
+ dptr = grid_oddcorners[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2oddcorner.size(); ++j) {
+ dptr[j] = grids[i].seq2oddcorner[j];
+ }
+ if (i + 1 < grids.size()) {
+ grid_downsamples[i] = torch::zeros({grids[i].downsample_seq.size()}, int64_options);
+ long* dptr = grid_downsamples[i].data_ptr();
+ for (int j = 0; j < grids[i].downsample_seq.size(); ++j) {
+ dptr[j] = grids[i].downsample_seq[j];
+ }
+ }
+
+ }
+ return {texture_positions, grid_neighbors, grid_downsamples, grid_evencorners, grid_oddcorners};
+}
+
+std::vector> build_hierarchy_with_feat(
+ std::vector view_layer_positions,
+ std::vector view_layer_normals,
+ std::vector view_layer_feats,
+ int num_level, int resolution)
+{
+ if (view_layer_positions.size() != 3 || num_level < 1) {
+ printf("Alert! We require 3 layers and at least 1 level! (%d %d)\n", view_layer_positions.size(), num_level);
+ return {{},{},{},{}};
+ }
+
+ std::vector grids;
+ grids.resize(num_level);
+
+ std::vector seq2pos;
+ std::vector seq2feat;
+ auto& seq2grid = grids[0].seq2grid;
+ auto& seq2normal = grids[0].seq2normal;
+ auto& grid2seq = grids[0].grid2seq;
+ grids[0].resolution = resolution;
+ grids[0].stride = 1;
+
+ auto int64_options = torch::TensorOptions().dtype(torch::kInt64).requires_grad(false);
+ auto float_options = torch::TensorOptions().dtype(torch::kFloat32).requires_grad(false);
+
+ int feat_channel = 3;
+ for (int v = 0; v < 3; ++v) {
+ int num_layers = view_layer_positions[v].size(0);
+ int height = view_layer_positions[v].size(1);
+ int width = view_layer_positions[v].size(2);
+ float* data = view_layer_positions[v].data_ptr();
+ float* data_normal = view_layer_normals[v].data_ptr();
+ float* data_feat = view_layer_feats[v].data_ptr();
+ feat_channel = view_layer_feats[v].size(3);
+ for (int l = 0; l < num_layers; ++l) {
+ for (int i = 0; i < height; ++i) {
+ for (int j = 0; j < width; ++j) {
+ float* p = &data[(i * width + j) * 4];
+ float* n = &data_normal[(i * width + j) * 3];
+ float* f = &data_feat[(i * width + j) * feat_channel];
+ if (p[3] == 0)
+ continue;
+ auto k = pos2key(p, resolution);
+ if (!grid2seq.count(k)) {
+ int dim = 0;
+ for (int d = 0; d < 3; ++d) {
+ if (std::abs(n[d]) > std::abs(n[dim]))
+ dim = d;
+ }
+ dim = (dim + 1) % 3;
+ grid2seq[k] = seq2grid.size();
+ seq2grid.emplace_back(k);
+ seq2pos.push_back(p[0]);
+ seq2pos.push_back(p[1]);
+ seq2pos.push_back(p[2]);
+ for (int c = 0; c < feat_channel; ++c) {
+ seq2feat.emplace_back(f[c]);
+ }
+ seq2normal.emplace_back(dim);
+ }
+ }
+ }
+ data += (height * width * 4);
+ data_normal += (height * width * 3);
+ data_feat += (height * width * feat_channel);
+ }
+ }
+
+ for (int i = 0; i < num_level - 1; ++i) {
+ DownsampleGrid(grids[i], grids[i + 1]);
+ }
+
+ for (int l = 0; l < num_level; ++l) {
+ grids[l].seq2neighbor.resize(grids[l].seq2grid.size() * 9, -1);
+ grids[l].num_origin_seq = grids[l].seq2grid.size();
+ for (int d = 0; d < 3; ++d) {
+ NeighborGrid(grids[l], view_layer_positions, d);
+ }
+ }
+
+ for (int i = num_level - 2; i >= 0; --i) {
+ PadGrid(grids[i], grids[i + 1], view_layer_positions);
+ }
+ for (int i = grids[0].num_origin_seq; i < grids[0].seq2grid.size(); ++i) {
+ int k = grids[0].seq2grid[i];
+ float p[3];
+ key2pos(k, grids[0].resolution, p);
+ seq2pos.push_back(p[0]);
+ seq2pos.push_back(p[1]);
+ seq2pos.push_back(p[2]);
+ for (int c = 0; c < feat_channel; ++c) {
+ seq2feat.emplace_back(0.5);
+ }
+ }
+
+ std::vector texture_positions(2);
+ std::vector texture_feats(1);
+ std::vector grid_neighbors(grids.size());
+ std::vector grid_downsamples(grids.size() - 1);
+ std::vector grid_evencorners(grids.size());
+ std::vector grid_oddcorners(grids.size());
+
+ texture_positions[0] = torch::zeros({seq2pos.size() / 3, 3}, float_options);
+ texture_positions[1] = torch::zeros({seq2pos.size() / 3}, float_options);
+ texture_feats[0] = torch::zeros({seq2feat.size() / feat_channel, feat_channel}, float_options);
+ float* positions_out_ptr = texture_positions[0].data_ptr();
+ memcpy(positions_out_ptr, seq2pos.data(), sizeof(float) * seq2pos.size());
+ positions_out_ptr = texture_positions[1].data_ptr();
+ for (int i = 0; i < grids[0].seq2grid.size(); ++i) {
+ positions_out_ptr[i] = (i < grids[0].num_origin_seq);
+ }
+ float* feats_out_ptr = texture_feats[0].data_ptr();
+ memcpy(feats_out_ptr, seq2feat.data(), sizeof(float) * seq2feat.size());
+
+ for (int i = 0; i < grids.size(); ++i) {
+ grid_neighbors[i] = torch::zeros({grids[i].seq2grid.size(), 9}, int64_options);
+ long* nptr = grid_neighbors[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2neighbor.size(); ++j) {
+ nptr[j] = grids[i].seq2neighbor[j];
+ }
+ grid_evencorners[i] = torch::zeros({grids[i].seq2evencorner.size()}, int64_options);
+ grid_oddcorners[i] = torch::zeros({grids[i].seq2oddcorner.size()}, int64_options);
+ long* dptr = grid_evencorners[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2evencorner.size(); ++j) {
+ dptr[j] = grids[i].seq2evencorner[j];
+ }
+ dptr = grid_oddcorners[i].data_ptr();
+ for (int j = 0; j < grids[i].seq2oddcorner.size(); ++j) {
+ dptr[j] = grids[i].seq2oddcorner[j];
+ }
+ if (i + 1 < grids.size()) {
+ grid_downsamples[i] = torch::zeros({grids[i].downsample_seq.size()}, int64_options);
+ long* dptr = grid_downsamples[i].data_ptr();
+ for (int j = 0; j < grids[i].downsample_seq.size(); ++j) {
+ dptr[j] = grids[i].downsample_seq[j];
+ }
+ }
+ }
+ return {texture_positions, texture_feats, grid_neighbors, grid_downsamples, grid_evencorners, grid_oddcorners};
+}
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.cpp b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b3ff69f5abe309be2784303d384524774708c2a3
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.cpp
@@ -0,0 +1,139 @@
+#include "rasterizer.h"
+
+void rasterizeTriangleCPU(int idx, float* vt0, float* vt1, float* vt2, int width, int height, INT64* zbuffer, float* d, float occlusion_truncation) {
+ float x_min = std::min(vt0[0], std::min(vt1[0],vt2[0]));
+ float x_max = std::max(vt0[0], std::max(vt1[0],vt2[0]));
+ float y_min = std::min(vt0[1], std::min(vt1[1],vt2[1]));
+ float y_max = std::max(vt0[1], std::max(vt1[1],vt2[1]));
+
+ for (int px = x_min; px < x_max + 1; ++px) {
+ if (px < 0 || px >= width)
+ continue;
+ for (int py = y_min; py < y_max + 1; ++py) {
+ if (py < 0 || py >= height)
+ continue;
+ float vt[2] = {px + 0.5, py + 0.5};
+ float baryCentricCoordinate[3];
+ calculateBarycentricCoordinate(vt0, vt1, vt2, vt, baryCentricCoordinate);
+ if (isBarycentricCoordInBounds(baryCentricCoordinate)) {
+ int pixel = py * width + px;
+ if (zbuffer == 0) {
+ zbuffer[pixel] = (INT64)(idx + 1);
+ continue;
+ }
+
+ float depth = baryCentricCoordinate[0] * vt0[2] + baryCentricCoordinate[1] * vt1[2] + baryCentricCoordinate[2] * vt2[2];
+ float depth_thres = 0;
+ if (d) {
+ depth_thres = d[pixel] * 0.49999f + 0.5f + occlusion_truncation;
+ }
+
+ int z_quantize = depth * (2<<17);
+ INT64 token = (INT64)z_quantize * MAXINT + (INT64)(idx + 1);
+ if (depth < depth_thres)
+ continue;
+ zbuffer[pixel] = std::min(zbuffer[pixel], token);
+ }
+ }
+ }
+}
+
+void barycentricFromImgcoordCPU(float* V, int* F, int* findices, INT64* zbuffer, int width, int height, int num_vertices, int num_faces,
+ float* barycentric_map, int pix)
+{
+ INT64 f = zbuffer[pix] % MAXINT;
+ if (f == (MAXINT-1)) {
+ findices[pix] = 0;
+ barycentric_map[pix * 3] = 0;
+ barycentric_map[pix * 3 + 1] = 0;
+ barycentric_map[pix * 3 + 2] = 0;
+ return;
+ }
+ findices[pix] = f;
+ f -= 1;
+ float barycentric[3] = {0, 0, 0};
+ if (f >= 0) {
+ float vt[2] = {float(pix % width) + 0.5f, float(pix / width) + 0.5f};
+ float* vt0_ptr = V + (F[f * 3] * 4);
+ float* vt1_ptr = V + (F[f * 3 + 1] * 4);
+ float* vt2_ptr = V + (F[f * 3 + 2] * 4);
+
+ float vt0[2] = {(vt0_ptr[0] / vt0_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt0_ptr[1] / vt0_ptr[3]) * (height - 1) + 0.5f};
+ float vt1[2] = {(vt1_ptr[0] / vt1_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt1_ptr[1] / vt1_ptr[3]) * (height - 1) + 0.5f};
+ float vt2[2] = {(vt2_ptr[0] / vt2_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt2_ptr[1] / vt2_ptr[3]) * (height - 1) + 0.5f};
+
+ calculateBarycentricCoordinate(vt0, vt1, vt2, vt, barycentric);
+
+ barycentric[0] = barycentric[0] / vt0_ptr[3];
+ barycentric[1] = barycentric[1] / vt1_ptr[3];
+ barycentric[2] = barycentric[2] / vt2_ptr[3];
+ float w = 1.0f / (barycentric[0] + barycentric[1] + barycentric[2]);
+ barycentric[0] *= w;
+ barycentric[1] *= w;
+ barycentric[2] *= w;
+
+ }
+ barycentric_map[pix * 3] = barycentric[0];
+ barycentric_map[pix * 3 + 1] = barycentric[1];
+ barycentric_map[pix * 3 + 2] = barycentric[2];
+}
+
+void rasterizeImagecoordsKernelCPU(float* V, int* F, float* d, INT64* zbuffer, float occlusion_trunc, int width, int height, int num_vertices, int num_faces, int f)
+{
+ float* vt0_ptr = V + (F[f * 3] * 4);
+ float* vt1_ptr = V + (F[f * 3 + 1] * 4);
+ float* vt2_ptr = V + (F[f * 3 + 2] * 4);
+
+ float vt0[3] = {(vt0_ptr[0] / vt0_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt0_ptr[1] / vt0_ptr[3]) * (height - 1) + 0.5f, vt0_ptr[2] / vt0_ptr[3] * 0.49999f + 0.5f};
+ float vt1[3] = {(vt1_ptr[0] / vt1_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt1_ptr[1] / vt1_ptr[3]) * (height - 1) + 0.5f, vt1_ptr[2] / vt1_ptr[3] * 0.49999f + 0.5f};
+ float vt2[3] = {(vt2_ptr[0] / vt2_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt2_ptr[1] / vt2_ptr[3]) * (height - 1) + 0.5f, vt2_ptr[2] / vt2_ptr[3] * 0.49999f + 0.5f};
+
+ rasterizeTriangleCPU(f, vt0, vt1, vt2, width, height, zbuffer, d, occlusion_trunc);
+}
+
+std::vector rasterize_image_cpu(torch::Tensor V, torch::Tensor F, torch::Tensor D,
+ int width, int height, float occlusion_truncation, int use_depth_prior)
+{
+ int num_faces = F.size(0);
+ int num_vertices = V.size(0);
+ auto options = torch::TensorOptions().dtype(torch::kInt32).requires_grad(false);
+ auto INT64_options = torch::TensorOptions().dtype(torch::kInt64).requires_grad(false);
+ auto findices = torch::zeros({height, width}, options);
+ INT64 maxint = (INT64)MAXINT * (INT64)MAXINT + (MAXINT - 1);
+ auto z_min = torch::ones({height, width}, INT64_options) * (long)maxint;
+
+ if (!use_depth_prior) {
+ for (int i = 0; i < num_faces; ++i) {
+ rasterizeImagecoordsKernelCPU(V.data_ptr(), F.data_ptr(), 0,
+ (INT64*)z_min.data_ptr(), occlusion_truncation, width, height, num_vertices, num_faces, i);
+ }
+ } else {
+ for (int i = 0; i < num_faces; ++i)
+ rasterizeImagecoordsKernelCPU(V.data_ptr(), F.data_ptr(), D.data_ptr(),
+ (INT64*)z_min.data_ptr(), occlusion_truncation, width, height, num_vertices, num_faces, i);
+ }
+
+ auto float_options = torch::TensorOptions().dtype(torch::kFloat32).requires_grad(false);
+ auto barycentric = torch::zeros({height, width, 3}, float_options);
+ for (int i = 0; i < width * height; ++i)
+ barycentricFromImgcoordCPU(V.data_ptr(), F.data_ptr(),
+ findices.data_ptr(), (INT64*)z_min.data_ptr(), width, height, num_vertices, num_faces, barycentric.data_ptr(), i);
+
+ return {findices, barycentric};
+}
+
+std::vector rasterize_image(torch::Tensor V, torch::Tensor F, torch::Tensor D,
+ int width, int height, float occlusion_truncation, int use_depth_prior)
+{
+ int device_id = V.get_device();
+ if (device_id == -1)
+ return rasterize_image_cpu(V, F, D, width, height, occlusion_truncation, use_depth_prior);
+ else
+ return rasterize_image_gpu(V, F, D, width, height, occlusion_truncation, use_depth_prior);
+}
+
+PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
+ m.def("rasterize_image", &rasterize_image, "Custom image rasterization");
+ m.def("build_hierarchy", &build_hierarchy, "Custom image rasterization");
+ m.def("build_hierarchy_with_feat", &build_hierarchy_with_feat, "Custom image rasterization");
+}
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.h b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf4f9870bda0714763e4236f85293ca7cef7d51f
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer.h
@@ -0,0 +1,54 @@
+#ifndef RASTERIZER_H_
+#define RASTERIZER_H_
+
+#include
+#include
+#include
+#include // For CUDA context
+
+#define INT64 unsigned long long
+#define MAXINT 2147483647
+
+__host__ __device__ inline float calculateSignedArea2(float* a, float* b, float* c) {
+ return ((c[0] - a[0]) * (b[1] - a[1]) - (b[0] - a[0]) * (c[1] - a[1]));
+}
+
+__host__ __device__ inline void calculateBarycentricCoordinate(float* a, float* b, float* c, float* p,
+ float* barycentric)
+{
+ float beta_tri = calculateSignedArea2(a, p, c);
+ float gamma_tri = calculateSignedArea2(a, b, p);
+ float area = calculateSignedArea2(a, b, c);
+ if (area == 0) {
+ barycentric[0] = -1.0;
+ barycentric[1] = -1.0;
+ barycentric[2] = -1.0;
+ return;
+ }
+ float tri_inv = 1.0 / area;
+ float beta = beta_tri * tri_inv;
+ float gamma = gamma_tri * tri_inv;
+ float alpha = 1.0 - beta - gamma;
+ barycentric[0] = alpha;
+ barycentric[1] = beta;
+ barycentric[2] = gamma;
+}
+
+__host__ __device__ inline bool isBarycentricCoordInBounds(float* barycentricCoord) {
+ return barycentricCoord[0] >= 0.0 && barycentricCoord[0] <= 1.0 &&
+ barycentricCoord[1] >= 0.0 && barycentricCoord[1] <= 1.0 &&
+ barycentricCoord[2] >= 0.0 && barycentricCoord[2] <= 1.0;
+}
+
+std::vector rasterize_image_gpu(torch::Tensor V, torch::Tensor F, torch::Tensor D,
+ int width, int height, float occlusion_truncation, int use_depth_prior);
+
+std::vector> build_hierarchy(std::vector view_layer_positions, std::vector view_layer_normals, int num_level, int resolution);
+
+std::vector> build_hierarchy_with_feat(
+ std::vector view_layer_positions,
+ std::vector view_layer_normals,
+ std::vector view_layer_feats,
+ int num_level, int resolution);
+
+#endif
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer_gpu.cu b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer_gpu.cu
new file mode 100644
index 0000000000000000000000000000000000000000..709c1b86a5ee92e3c2ff6ce9df85f1492c3c5378
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/lib/custom_rasterizer_kernel/rasterizer_gpu.cu
@@ -0,0 +1,127 @@
+#include "rasterizer.h"
+
+__device__ void rasterizeTriangleGPU(int idx, float* vt0, float* vt1, float* vt2, int width, int height, INT64* zbuffer, float* d, float occlusion_truncation) {
+ float x_min = std::min(vt0[0], std::min(vt1[0],vt2[0]));
+ float x_max = std::max(vt0[0], std::max(vt1[0],vt2[0]));
+ float y_min = std::min(vt0[1], std::min(vt1[1],vt2[1]));
+ float y_max = std::max(vt0[1], std::max(vt1[1],vt2[1]));
+
+ for (int px = x_min; px < x_max + 1; ++px) {
+ if (px < 0 || px >= width)
+ continue;
+ for (int py = y_min; py < y_max + 1; ++py) {
+ if (py < 0 || py >= height)
+ continue;
+ float vt[2] = {px + 0.5f, py + 0.5f};
+ float baryCentricCoordinate[3];
+ calculateBarycentricCoordinate(vt0, vt1, vt2, vt, baryCentricCoordinate);
+ if (isBarycentricCoordInBounds(baryCentricCoordinate)) {
+ int pixel = py * width + px;
+ if (zbuffer == 0) {
+ atomicExch(&zbuffer[pixel], (INT64)(idx + 1));
+ continue;
+ }
+ float depth = baryCentricCoordinate[0] * vt0[2] + baryCentricCoordinate[1] * vt1[2] + baryCentricCoordinate[2] * vt2[2];
+ float depth_thres = 0;
+ if (d) {
+ depth_thres = d[pixel] * 0.49999f + 0.5f + occlusion_truncation;
+ }
+
+ int z_quantize = depth * (2<<17);
+ INT64 token = (INT64)z_quantize * MAXINT + (INT64)(idx + 1);
+ if (depth < depth_thres)
+ continue;
+ atomicMin(&zbuffer[pixel], token);
+ }
+ }
+ }
+}
+
+__global__ void barycentricFromImgcoordGPU(float* V, int* F, int* findices, INT64* zbuffer, int width, int height, int num_vertices, int num_faces,
+ float* barycentric_map)
+{
+ int pix = blockIdx.x * blockDim.x + threadIdx.x;
+ if (pix >= width * height)
+ return;
+ INT64 f = zbuffer[pix] % MAXINT;
+ if (f == (MAXINT-1)) {
+ findices[pix] = 0;
+ barycentric_map[pix * 3] = 0;
+ barycentric_map[pix * 3 + 1] = 0;
+ barycentric_map[pix * 3 + 2] = 0;
+ return;
+ }
+ findices[pix] = f;
+ f -= 1;
+ float barycentric[3] = {0, 0, 0};
+ if (f >= 0) {
+ float vt[2] = {float(pix % width) + 0.5f, float(pix / width) + 0.5f};
+ float* vt0_ptr = V + (F[f * 3] * 4);
+ float* vt1_ptr = V + (F[f * 3 + 1] * 4);
+ float* vt2_ptr = V + (F[f * 3 + 2] * 4);
+
+ float vt0[2] = {(vt0_ptr[0] / vt0_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt0_ptr[1] / vt0_ptr[3]) * (height - 1) + 0.5f};
+ float vt1[2] = {(vt1_ptr[0] / vt1_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt1_ptr[1] / vt1_ptr[3]) * (height - 1) + 0.5f};
+ float vt2[2] = {(vt2_ptr[0] / vt2_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt2_ptr[1] / vt2_ptr[3]) * (height - 1) + 0.5f};
+
+ calculateBarycentricCoordinate(vt0, vt1, vt2, vt, barycentric);
+
+ barycentric[0] = barycentric[0] / vt0_ptr[3];
+ barycentric[1] = barycentric[1] / vt1_ptr[3];
+ barycentric[2] = barycentric[2] / vt2_ptr[3];
+ float w = 1.0f / (barycentric[0] + barycentric[1] + barycentric[2]);
+ barycentric[0] *= w;
+ barycentric[1] *= w;
+ barycentric[2] *= w;
+
+ }
+ barycentric_map[pix * 3] = barycentric[0];
+ barycentric_map[pix * 3 + 1] = barycentric[1];
+ barycentric_map[pix * 3 + 2] = barycentric[2];
+}
+
+__global__ void rasterizeImagecoordsKernelGPU(float* V, int* F, float* d, INT64* zbuffer, float occlusion_trunc, int width, int height, int num_vertices, int num_faces)
+{
+ int f = blockIdx.x * blockDim.x + threadIdx.x;
+ if (f >= num_faces)
+ return;
+
+ float* vt0_ptr = V + (F[f * 3] * 4);
+ float* vt1_ptr = V + (F[f * 3 + 1] * 4);
+ float* vt2_ptr = V + (F[f * 3 + 2] * 4);
+
+ float vt0[3] = {(vt0_ptr[0] / vt0_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt0_ptr[1] / vt0_ptr[3]) * (height - 1) + 0.5f, vt0_ptr[2] / vt0_ptr[3] * 0.49999f + 0.5f};
+ float vt1[3] = {(vt1_ptr[0] / vt1_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt1_ptr[1] / vt1_ptr[3]) * (height - 1) + 0.5f, vt1_ptr[2] / vt1_ptr[3] * 0.49999f + 0.5f};
+ float vt2[3] = {(vt2_ptr[0] / vt2_ptr[3] * 0.5f + 0.5f) * (width - 1) + 0.5f, (0.5f + 0.5f * vt2_ptr[1] / vt2_ptr[3]) * (height - 1) + 0.5f, vt2_ptr[2] / vt2_ptr[3] * 0.49999f + 0.5f};
+
+ rasterizeTriangleGPU(f, vt0, vt1, vt2, width, height, zbuffer, d, occlusion_trunc);
+}
+
+std::vector rasterize_image_gpu(torch::Tensor V, torch::Tensor F, torch::Tensor D,
+ int width, int height, float occlusion_truncation, int use_depth_prior)
+{
+ int device_id = V.get_device();
+ cudaSetDevice(device_id);
+ int num_faces = F.size(0);
+ int num_vertices = V.size(0);
+ auto options = torch::TensorOptions().dtype(torch::kInt32).device(torch::kCUDA, device_id).requires_grad(false);
+ auto INT64_options = torch::TensorOptions().dtype(torch::kInt64).device(torch::kCUDA, device_id).requires_grad(false);
+ auto findices = torch::zeros({height, width}, options);
+ INT64 maxint = (INT64)MAXINT * (INT64)MAXINT + (MAXINT - 1);
+ auto z_min = torch::ones({height, width}, INT64_options) * (long)maxint;
+
+ if (!use_depth_prior) {
+ rasterizeImagecoordsKernelGPU<<<(num_faces+255)/256,256,0,at::cuda::getCurrentCUDAStream()>>>(V.data_ptr(), F.data_ptr(), 0,
+ (INT64*)z_min.data_ptr(), occlusion_truncation, width, height, num_vertices, num_faces);
+ } else {
+ rasterizeImagecoordsKernelGPU<<<(num_faces+255)/256,256,0,at::cuda::getCurrentCUDAStream()>>>(V.data_ptr(), F.data_ptr(), D.data_ptr(),
+ (INT64*)z_min.data_ptr(), occlusion_truncation, width, height, num_vertices, num_faces);
+ }
+
+ auto float_options = torch::TensorOptions().dtype(torch::kFloat32).device(torch::kCUDA, device_id).requires_grad(false);
+ auto barycentric = torch::zeros({height, width, 3}, float_options);
+ barycentricFromImgcoordGPU<<<(width * height + 255)/256, 256>>>(V.data_ptr(), F.data_ptr(),
+ findices.data_ptr(), (INT64*)z_min.data_ptr(), width, height, num_vertices, num_faces, barycentric.data_ptr());
+
+ return {findices, barycentric};
+}
diff --git a/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/setup.py b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..15192e9f5e1f4b0308ed6f1fdd3c93df8c35feef
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/packages/custom_rasterizer/setup.py
@@ -0,0 +1,40 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from setuptools import setup, find_packages
+import torch
+from torch.utils.cpp_extension import BuildExtension, CUDAExtension, CppExtension
+
+# build custom rasterizer
+
+custom_rasterizer_module = CUDAExtension(
+ "custom_rasterizer_kernel",
+ [
+ "lib/custom_rasterizer_kernel/rasterizer.cpp",
+ "lib/custom_rasterizer_kernel/grid_neighbor.cpp",
+ "lib/custom_rasterizer_kernel/rasterizer_gpu.cu",
+ ],
+)
+
+setup(
+ packages=find_packages(),
+ version="0.1",
+ name="custom_rasterizer",
+ include_package_data=True,
+ package_dir={"": "."},
+ ext_modules=[
+ custom_rasterizer_module,
+ ],
+ cmdclass={"build_ext": BuildExtension},
+)
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/__init__.py b/Hunyuan3D-2.1/hy3dpaint/src/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1614ff826f65b4720649d343c43fb09dbb6b9fa5
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/__init__.py
@@ -0,0 +1,13 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/data/__init__.py b/Hunyuan3D-2.1/hy3dpaint/src/data/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1614ff826f65b4720649d343c43fb09dbb6b9fa5
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/data/__init__.py
@@ -0,0 +1,13 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/loader_util.py b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/loader_util.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f81adcb79601619e1e2ff3a073076f79574d19a
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/loader_util.py
@@ -0,0 +1,219 @@
+#!/usr/bin/env python3
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import cv2
+import json
+import random
+import numpy as np
+import torch
+from torch.utils.data import Dataset
+from PIL import Image, ImageOps, ImageChops
+
+
+class BaseDataset(Dataset):
+ def __init__(self, json_path, num_view=4, image_size=512):
+ self.data = list()
+ self.num_view = num_view
+ self.image_size = image_size
+ if isinstance(json_path, str):
+ json_path = [json_path]
+ for jp in json_path:
+ with open(jp) as f:
+ self.data.extend(json.load(f))
+ print("============= length of dataset %d =============" % len(self.data))
+
+ def __len__(self):
+ return len(self.data)
+
+ def load_image(self, pil_img, color, image_size=None):
+ if image_size is None:
+ image_size = self.image_size
+ if isinstance(pil_img, str):
+ pil_img = Image.open(pil_img)
+ else:
+ pil_img = pil_img
+ if pil_img.mode == "L":
+ pil_img = pil_img.convert("RGB")
+ pil_img = pil_img.resize((image_size, image_size))
+ image = np.asarray(pil_img, dtype=np.float32) / 255.0
+ if image.shape[2] == 3:
+ image = image[:, :, :3]
+ alpha = np.ones_like(image)
+ else:
+ alpha = image[:, :, 3:]
+ image = image[:, :, :3] * alpha + color * (1 - alpha)
+ image = torch.from_numpy(image).permute(2, 0, 1).contiguous().float()
+ alpha = torch.from_numpy(alpha).permute(2, 0, 1).contiguous().float()
+ return image, alpha
+
+ def _apply_scaling(self, image, scale_factor, width, height, bg_color, scale_width=True):
+ """Apply scaling to image with proper cropping or padding."""
+ if scale_width:
+ new_width = int(width * scale_factor)
+ new_height = height
+ else:
+ new_width = width
+ new_height = int(height * scale_factor)
+
+ image = image.resize((new_width, new_height), resample=Image.BILINEAR)
+
+ if scale_factor > 1.0:
+ # Crop to original size
+ left = (new_width - width) // 2
+ top = (new_height - height) // 2
+ image = image.crop((left, top, left + width, top + height))
+ else:
+ # Pad to original size
+ pad_width = (width - new_width) // 2
+ pad_height = (height - new_height) // 2
+ image = ImageOps.expand(
+ image,
+ (
+ pad_width,
+ pad_height,
+ width - new_width - pad_width,
+ height - new_height - pad_height,
+ ),
+ fill=bg_color,
+ )
+ return image
+
+ def _apply_rotation(self, image, bg_color):
+ """Apply random rotation to image."""
+ original_size = image.size
+ angle = random.uniform(-30, 30)
+ image = image.convert("RGBA")
+ rotated_image = image.rotate(angle, resample=Image.BILINEAR, expand=True)
+
+ # Create background with bg_color
+ background = Image.new("RGBA", rotated_image.size, (bg_color[0], bg_color[1], bg_color[2], 255))
+ background.paste(rotated_image, (0, 0), rotated_image)
+ image = background.convert("RGB")
+
+ # Crop to original size
+ left = (image.width - original_size[0]) // 2
+ top = (image.height - original_size[1]) // 2
+ right = left + original_size[0]
+ bottom = top + original_size[1]
+
+ return image.crop((left, top, right, bottom))
+
+ def _apply_translation(self, image, bg_color):
+ """Apply random translation to image."""
+ max_dx = 0.1 * image.size[0]
+ max_dy = 0.1 * image.size[1]
+ dx = int(random.uniform(-max_dx, max_dx))
+ dy = int(random.uniform(-max_dy, max_dy))
+
+ image = ImageChops.offset(image, dx, dy)
+
+ # Fill edges
+ width, height = image.size
+ if dx > 0:
+ image.paste(bg_color, (0, 0, dx, height))
+ elif dx < 0:
+ image.paste(bg_color, (width + dx, 0, width, height))
+
+ if dy > 0:
+ image.paste(bg_color, (0, 0, width, dy))
+ elif dy < 0:
+ image.paste(bg_color, (0, height + dy, width, height))
+
+ return image
+
+ def _apply_perspective(self, image, bg_color):
+ """Apply random perspective transformation to image."""
+ image_np = np.array(image)
+ height, width = image_np.shape[:2]
+
+ # Define original and new points
+ original_points = np.float32([[0, 0], [width, 0], [width, height], [0, height]])
+ perspective_scale = 0.2
+
+ new_points = np.float32(
+ [
+ [random.uniform(0, width * perspective_scale), random.uniform(0, height * perspective_scale)],
+ [random.uniform(width * (1 - perspective_scale), width), random.uniform(0, height * perspective_scale)],
+ [
+ random.uniform(width * (1 - perspective_scale), width),
+ random.uniform(height * (1 - perspective_scale), height),
+ ],
+ [
+ random.uniform(0, width * perspective_scale),
+ random.uniform(height * (1 - perspective_scale), height),
+ ],
+ ]
+ )
+
+ matrix = cv2.getPerspectiveTransform(original_points, new_points)
+ image_np = cv2.warpPerspective(
+ image_np, matrix, (width, height), borderMode=cv2.BORDER_CONSTANT, borderValue=bg_color
+ )
+
+ return Image.fromarray(image_np)
+
+ def augment_image(
+ self,
+ image,
+ bg_color,
+ identity_prob=0.5,
+ rotate_prob=0.3,
+ scale_prob=0.5,
+ translate_prob=0.5,
+ perspective_prob=0.3,
+ ):
+ if random.random() < identity_prob:
+ return image
+
+ # Convert torch tensors back to PIL images for augmentation
+ image = Image.fromarray((image.permute(1, 2, 0).cpu().numpy() * 255).astype(np.uint8))
+ bg_color = (int(bg_color[0] * 255), int(bg_color[1] * 255), int(bg_color[2] * 255))
+
+ # Random rotation
+ if random.random() < rotate_prob:
+ image = self._apply_rotation(image, bg_color)
+
+ # Random scaling
+ if random.random() < scale_prob:
+ width, height = image.size
+ scale_factor = random.uniform(0.8, 1.2)
+
+ if random.random() < 0.5:
+ # Scale both dimensions proportionally
+ image = self._apply_scaling(image, scale_factor, width, height, bg_color, scale_width=True)
+ image = self._apply_scaling(image, scale_factor, width, height, bg_color, scale_width=False)
+ else:
+ # Scale width then height independently
+ scale_factor_w = random.uniform(0.8, 1.2)
+ scale_factor_h = random.uniform(0.8, 1.2)
+ image = self._apply_scaling(image, scale_factor_w, width, height, bg_color, scale_width=True)
+ image = self._apply_scaling(image, scale_factor_h, width, height, bg_color, scale_width=False)
+
+ # Random translation
+ if random.random() < translate_prob:
+ image = self._apply_translation(image, bg_color)
+
+ # Random perspective
+ if random.random() < perspective_prob:
+ image = self._apply_perspective(image, bg_color)
+
+ # Convert back to torch tensors
+ image = image.convert("RGB")
+ image = np.asarray(image, dtype=np.float32) / 255.0
+ image = torch.from_numpy(image).permute(2, 0, 1).contiguous().float()
+
+ return image
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/objaverse_loader_forTexturePBR.py b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/objaverse_loader_forTexturePBR.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce488d6ea36f75f7b188fd6e0f22da2e1e416480
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/objaverse_loader_forTexturePBR.py
@@ -0,0 +1,146 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import time
+import glob
+import json
+import random
+import numpy as np
+import torch
+from .loader_util import BaseDataset
+
+
+class TextureDataset(BaseDataset):
+
+ def __init__(
+ self, json_path, num_view=6, image_size=512, lighting_suffix_pool=["light_PL", "light_AL", "light_ENVMAP"]
+ ):
+ self.data = list()
+ self.num_view = num_view
+ self.image_size = image_size
+ self.lighting_suffix_pool = lighting_suffix_pool
+ if isinstance(json_path, str):
+ json_path = [json_path]
+ for jp in json_path:
+ with open(jp) as f:
+ self.data.extend(json.load(f))
+ print("============= length of dataset %d =============" % len(self.data))
+
+ def __getitem__(self, index):
+ try_sleep_interval = 20
+ total_try_num = 100
+ cnt = try_sleep_interval * total_try_num
+ # try:
+ images_ref = list()
+ images_albedo = list()
+ images_mr = list()
+ images_normal = list()
+ images_position = list()
+ bg_white = [1.0, 1.0, 1.0]
+ bg_black = [0.0, 0.0, 0.0]
+ bg_gray = [127 / 255.0, 127 / 255.0, 127 / 255.0]
+ dirx = self.data[index]
+
+ condition_dict = {}
+
+ # 6view
+ fix_num_view = self.num_view
+ available_views = []
+ for ext in ["*_albedo.png", "*_albedo.jpg", "*_albedo.jpeg"]:
+ available_views.extend(glob.glob(os.path.join(dirx, "render_tex", ext)))
+ cond_images = (
+ glob.glob(os.path.join(dirx, "render_cond", "*.png"))
+ + glob.glob(os.path.join(dirx, "render_cond", "*.jpg"))
+ + glob.glob(os.path.join(dirx, "render_cond", "*.jpeg"))
+ )
+
+ # 确保有足够的样本
+ if len(available_views) < fix_num_view:
+ print(
+ f"Warning: Only {len(available_views)} views available, but {fix_num_view} requested."
+ "Using all available views."
+ )
+ images_gen = available_views
+ else:
+ images_gen = random.sample(available_views, fix_num_view)
+
+ if not cond_images:
+ raise ValueError(f"No condition images found in {os.path.join(dirx, 'render_cond')}")
+ ref_image_path = random.choice(cond_images)
+ light_suffix = None
+ for suffix in self.lighting_suffix_pool:
+ if suffix in ref_image_path:
+ light_suffix = suffix
+ break
+ if light_suffix is None:
+ raise ValueError(f"light suffix not found in {ref_image_path}")
+ ref_image_diff_light_path = random.choice(
+ [
+ ref_image_path.replace(light_suffix, tar_suffix)
+ for tar_suffix in self.lighting_suffix_pool
+ if tar_suffix != light_suffix
+ ]
+ )
+ images_ref_paths = [ref_image_path, ref_image_diff_light_path]
+
+ # Data aug
+ bg_c_record = None
+ for i, image_ref in enumerate(images_ref_paths):
+ if random.random() < 0.6:
+ bg_c = bg_gray
+ else:
+ if random.random() < 0.5:
+ bg_c = bg_black
+ else:
+ bg_c = bg_white
+ if i == 0:
+ bg_c_record = bg_c
+ image, alpha = self.load_image(image_ref, bg_c_record)
+ image = self.augment_image(image, bg_c_record).float()
+ images_ref.append(image)
+ condition_dict["images_cond"] = torch.stack(images_ref, dim=0).float()
+
+ for i, image_gen in enumerate(images_gen):
+ images_albedo.append(self.augment_image(self.load_image(image_gen, bg_gray)[0], bg_gray))
+ images_mr.append(
+ self.augment_image(self.load_image(image_gen.replace("_albedo", "_mr"), bg_gray)[0], bg_gray)
+ )
+ images_normal.append(
+ self.augment_image(self.load_image(image_gen.replace("_albedo", "_normal"), bg_gray)[0], bg_gray)
+ )
+ images_position.append(
+ self.augment_image(self.load_image(image_gen.replace("_albedo", "_pos"), bg_gray)[0], bg_gray)
+ )
+
+ condition_dict["images_albedo"] = torch.stack(images_albedo, dim=0).float()
+ condition_dict["images_mr"] = torch.stack(images_mr, dim=0).float()
+ condition_dict["images_normal"] = torch.stack(images_normal, dim=0).float()
+ condition_dict["images_position"] = torch.stack(images_position, dim=0).float()
+ condition_dict["name"] = dirx # .replace('/', '_')
+ return condition_dict # (N, 3, H, W)
+
+ # except Exception as e:
+ # print(e, self.data[index])
+ # # exit()
+
+
+if __name__ == "__main__":
+ dataset = TextureDataset(json_path=["../../../train_examples/examples.json"])
+ print("images_cond", dataset[0]["images_cond"].shape)
+ print("images_albedo", dataset[0]["images_albedo"].shape)
+ print("images_mr", dataset[0]["images_mr"].shape)
+ print("images_normal", dataset[0]["images_normal"].shape)
+ print("images_position", dataset[0]["images_position"].shape)
+ print("name", dataset[0]["name"])
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/pbr_data_format.txt b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/pbr_data_format.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9fd97d049194b788a735ac4814794c05bb3553ca
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/data/dataloader/pbr_data_format.txt
@@ -0,0 +1,10 @@
++-----------------+----------------------------------+
+| Key | Value |
++-----------------+----------------------------------+
+| images_cond | torch.Size([2, 2, 3, 512, 512]) |
+| images_albedo | torch.Size([2, 6, 3, 512, 512]) |
+| images_mr | torch.Size([2, 6, 3, 512, 512]) |
+| images_normal | torch.Size([2, 6, 3, 512, 512]) |
+| images_position | torch.Size([2, 6, 3, 512, 512]) |
+| caption | ['high quality', 'high quality'] |
++-----------------+----------------------------------+
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/data/objaverse_hunyuan.py b/Hunyuan3D-2.1/hy3dpaint/src/data/objaverse_hunyuan.py
new file mode 100644
index 0000000000000000000000000000000000000000..94e578220809673f5880f76b0f9b55f4ad99ac71
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/data/objaverse_hunyuan.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import pytorch_lightning as pl
+from torch.utils.data import Dataset, ConcatDataset, DataLoader
+from torch.utils.data.distributed import DistributedSampler
+
+
+class DataModuleFromConfig(pl.LightningDataModule):
+ def __init__(
+ self,
+ batch_size=8,
+ num_workers=4,
+ train=None,
+ validation=None,
+ test=None,
+ **kwargs,
+ ):
+ super().__init__()
+
+ self.batch_size = batch_size
+ self.num_workers = num_workers
+
+ self.dataset_configs = dict()
+ if train is not None:
+ self.dataset_configs["train"] = train
+ if validation is not None:
+ self.dataset_configs["validation"] = validation
+ if test is not None:
+ self.dataset_configs["test"] = test
+
+ def setup(self, stage):
+ from src.utils.train_util import instantiate_from_config
+
+ if stage in ["fit"]:
+ dataset_dict = {}
+ for k in self.dataset_configs:
+ dataset_dict[k] = []
+ for loader in self.dataset_configs[k]:
+ dataset_dict[k].append(instantiate_from_config(loader))
+ self.datasets = dataset_dict
+ print(self.datasets)
+ else:
+ raise NotImplementedError
+
+ def train_dataloader(self):
+ datasets = ConcatDataset(self.datasets["train"])
+ sampler = DistributedSampler(datasets)
+ return DataLoader(
+ datasets,
+ batch_size=self.batch_size,
+ num_workers=self.num_workers,
+ shuffle=False,
+ sampler=sampler,
+ prefetch_factor=2,
+ pin_memory=True,
+ )
+
+ def val_dataloader(self):
+ datasets = ConcatDataset(self.datasets["validation"])
+ sampler = DistributedSampler(datasets)
+ return DataLoader(datasets, batch_size=4, num_workers=self.num_workers, shuffle=False, sampler=sampler)
+
+ def test_dataloader(self):
+ datasets = ConcatDataset(self.datasets["test"])
+ return DataLoader(datasets, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=False)
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/utils/__init__.py b/Hunyuan3D-2.1/hy3dpaint/src/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1614ff826f65b4720649d343c43fb09dbb6b9fa5
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/utils/__init__.py
@@ -0,0 +1,13 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
diff --git a/Hunyuan3D-2.1/hy3dpaint/src/utils/train_util.py b/Hunyuan3D-2.1/hy3dpaint/src/utils/train_util.py
new file mode 100644
index 0000000000000000000000000000000000000000..dff39da91cc24c812251728c786ad0509c544351
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/src/utils/train_util.py
@@ -0,0 +1,40 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import importlib
+
+
+def count_params(model, verbose=False):
+ total_params = sum(p.numel() for p in model.parameters())
+ if verbose:
+ print(f"{model.__class__.__name__} has {total_params*1.e-6:.2f} M params.")
+ return total_params
+
+
+def instantiate_from_config(config):
+ if not "target" in config:
+ if config == "__is_first_stage__":
+ return None
+ elif config == "__is_unconditional__":
+ return None
+ raise KeyError("Expected key `target` to instantiate.")
+ return get_obj_from_str(config["target"])(**config.get("params", dict()))
+
+
+def get_obj_from_str(string, reload=False):
+ module, cls = string.rsplit(".", 1)
+ if reload:
+ module_imp = importlib.import_module(module)
+ importlib.reload(module_imp)
+ return getattr(importlib.import_module(module, package=None), cls)
diff --git a/Hunyuan3D-2.1/hy3dpaint/textureGenPipeline.py b/Hunyuan3D-2.1/hy3dpaint/textureGenPipeline.py
new file mode 100644
index 0000000000000000000000000000000000000000..9396eea492f88f5b10c3c44d8ef14a1540055fc3
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/textureGenPipeline.py
@@ -0,0 +1,192 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import torch
+import copy
+import trimesh
+import numpy as np
+from PIL import Image
+from typing import List
+from DifferentiableRenderer.MeshRender import MeshRender
+from utils.simplify_mesh_utils import remesh_mesh
+from utils.multiview_utils import multiviewDiffusionNet
+from utils.pipeline_utils import ViewProcessor
+from utils.image_super_utils import imageSuperNet
+from utils.uvwrap_utils import mesh_uv_wrap
+from DifferentiableRenderer.mesh_utils import convert_obj_to_glb
+import warnings
+
+warnings.filterwarnings("ignore")
+from diffusers.utils import logging as diffusers_logging
+
+diffusers_logging.set_verbosity(50)
+
+
+class Hunyuan3DPaintConfig:
+ def __init__(self, max_num_view, resolution):
+ self.device = "cuda"
+
+ self.multiview_cfg_path = "cfgs/hunyuan-paint-pbr.yaml"
+ self.custom_pipeline = "hunyuanpaintpbr"
+ self.multiview_pretrained_path = "tencent/Hunyuan3D-2.1"
+ self.dino_ckpt_path = "facebook/dinov2-giant"
+ self.realesrgan_ckpt_path = "ckpt/RealESRGAN_x4plus.pth"
+
+ self.raster_mode = "cr"
+ self.bake_mode = "back_sample"
+ self.render_size = 1024 * 2
+ self.texture_size = 1024 * 4
+ self.max_selected_view_num = max_num_view
+ self.resolution = resolution
+ self.bake_exp = 4
+ self.merge_method = "fast"
+
+ # view selection
+ self.candidate_camera_azims = [0, 90, 180, 270, 0, 180]
+ self.candidate_camera_elevs = [0, 0, 0, 0, 90, -90]
+ self.candidate_view_weights = [1, 0.1, 0.5, 0.1, 0.05, 0.05]
+
+ for azim in range(0, 360, 30):
+ self.candidate_camera_azims.append(azim)
+ self.candidate_camera_elevs.append(20)
+ self.candidate_view_weights.append(0.01)
+
+ self.candidate_camera_azims.append(azim)
+ self.candidate_camera_elevs.append(-20)
+ self.candidate_view_weights.append(0.01)
+
+
+class Hunyuan3DPaintPipeline:
+
+ def __init__(self, config=None) -> None:
+ self.config = config if config is not None else Hunyuan3DPaintConfig()
+ self.models = {}
+ self.stats_logs = {}
+ self.render = MeshRender(
+ default_resolution=self.config.render_size,
+ texture_size=self.config.texture_size,
+ bake_mode=self.config.bake_mode,
+ raster_mode=self.config.raster_mode,
+ )
+ self.view_processor = ViewProcessor(self.config, self.render)
+ self.load_models()
+
+ def load_models(self):
+ torch.cuda.empty_cache()
+ self.models["super_model"] = imageSuperNet(self.config)
+ self.models["multiview_model"] = multiviewDiffusionNet(self.config)
+ print("Models Loaded.")
+
+ @torch.no_grad()
+ def __call__(self, mesh_path=None, image_path=None, output_mesh_path=None, use_remesh=True, save_glb=True):
+ """Generate texture for 3D mesh using multiview diffusion"""
+ # Ensure image_prompt is a list
+ if isinstance(image_path, str):
+ image_prompt = Image.open(image_path)
+ elif isinstance(image_path, Image.Image):
+ image_prompt = image_path
+ if not isinstance(image_prompt, List):
+ image_prompt = [image_prompt]
+ else:
+ image_prompt = image_path
+
+ # Process mesh
+ path = os.path.dirname(mesh_path)
+ if use_remesh:
+ processed_mesh_path = os.path.join(path, "white_mesh_remesh.obj")
+ remesh_mesh(mesh_path, processed_mesh_path)
+ else:
+ processed_mesh_path = mesh_path
+
+ # Output path
+ if output_mesh_path is None:
+ output_mesh_path = os.path.join(path, f"textured_mesh.obj")
+
+ # Load mesh
+ mesh = trimesh.load(processed_mesh_path)
+ mesh = mesh_uv_wrap(mesh)
+ self.render.load_mesh(mesh=mesh)
+
+ ########### View Selection #########
+ selected_camera_elevs, selected_camera_azims, selected_view_weights = self.view_processor.bake_view_selection(
+ self.config.candidate_camera_elevs,
+ self.config.candidate_camera_azims,
+ self.config.candidate_view_weights,
+ self.config.max_selected_view_num,
+ )
+
+ normal_maps = self.view_processor.render_normal_multiview(
+ selected_camera_elevs, selected_camera_azims, use_abs_coor=True
+ )
+ position_maps = self.view_processor.render_position_multiview(selected_camera_elevs, selected_camera_azims)
+
+ ########## Style ###########
+ image_caption = "high quality"
+ image_style = []
+ for image in image_prompt:
+ image = image.resize((512, 512))
+ if image.mode == "RGBA":
+ white_bg = Image.new("RGB", image.size, (255, 255, 255))
+ white_bg.paste(image, mask=image.getchannel("A"))
+ image = white_bg
+ image_style.append(image)
+ image_style = [image.convert("RGB") for image in image_style]
+
+ ########### Multiview ##########
+ multiviews_pbr = self.models["multiview_model"](
+ image_style,
+ normal_maps + position_maps,
+ prompt=image_caption,
+ custom_view_size=self.config.resolution,
+ resize_input=True,
+ )
+ ########### Enhance ##########
+ enhance_images = {}
+ enhance_images["albedo"] = copy.deepcopy(multiviews_pbr["albedo"])
+ enhance_images["mr"] = copy.deepcopy(multiviews_pbr["mr"])
+
+ for i in range(len(enhance_images["albedo"])):
+ enhance_images["albedo"][i] = self.models["super_model"](enhance_images["albedo"][i])
+ enhance_images["mr"][i] = self.models["super_model"](enhance_images["mr"][i])
+
+ ########### Bake ##########
+ for i in range(len(enhance_images)):
+ enhance_images["albedo"][i] = enhance_images["albedo"][i].resize(
+ (self.config.render_size, self.config.render_size)
+ )
+ enhance_images["mr"][i] = enhance_images["mr"][i].resize((self.config.render_size, self.config.render_size))
+ texture, mask = self.view_processor.bake_from_multiview(
+ enhance_images["albedo"], selected_camera_elevs, selected_camera_azims, selected_view_weights
+ )
+ mask_np = (mask.squeeze(-1).cpu().numpy() * 255).astype(np.uint8)
+ texture_mr, mask_mr = self.view_processor.bake_from_multiview(
+ enhance_images["mr"], selected_camera_elevs, selected_camera_azims, selected_view_weights
+ )
+ mask_mr_np = (mask_mr.squeeze(-1).cpu().numpy() * 255).astype(np.uint8)
+
+ ########## inpaint ###########
+ texture = self.view_processor.texture_inpaint(texture, mask_np)
+ self.render.set_texture(texture, force_set=True)
+ if "mr" in enhance_images:
+ texture_mr = self.view_processor.texture_inpaint(texture_mr, mask_mr_np)
+ self.render.set_texture_mr(texture_mr)
+
+ self.render.save_mesh(output_mesh_path, downsample=True)
+
+ if save_glb:
+ convert_obj_to_glb(output_mesh_path, output_mesh_path.replace(".obj", ".glb"))
+ output_glb_path = output_mesh_path.replace(".obj", ".glb")
+
+ return output_mesh_path
diff --git a/Hunyuan3D-2.1/hy3dpaint/train.py b/Hunyuan3D-2.1/hy3dpaint/train.py
new file mode 100644
index 0000000000000000000000000000000000000000..289f74b8e44b9c9931cc3dc749c9ca102811d62e
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/train.py
@@ -0,0 +1,401 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import torch
+import os, sys
+import argparse
+import shutil
+import subprocess
+from omegaconf import OmegaConf
+
+from pytorch_lightning import seed_everything
+from pytorch_lightning.trainer import Trainer
+from pytorch_lightning.strategies import DDPStrategy
+from pytorch_lightning.callbacks import Callback
+from pytorch_lightning.utilities import rank_zero_only, rank_zero_warn
+
+from src.utils.train_util import instantiate_from_config
+import warnings
+
+warnings.filterwarnings("ignore")
+from diffusers.utils import logging as diffusers_logging
+
+diffusers_logging.set_verbosity(50)
+
+
+@rank_zero_only
+def rank_zero_print(*args):
+ print(*args)
+
+
+def get_parser(**parser_kwargs):
+ def str2bool(v):
+ if isinstance(v, bool):
+ return v
+ if v.lower() in ("yes", "true", "t", "y", "1"):
+ return True
+ elif v.lower() in ("no", "false", "f", "n", "0"):
+ return False
+ else:
+ raise argparse.ArgumentTypeError("Boolean value expected.")
+
+ parser = argparse.ArgumentParser(**parser_kwargs)
+ parser.add_argument(
+ "-r",
+ "--resume",
+ type=str,
+ default=None,
+ help="resume from checkpoint",
+ )
+ parser.add_argument(
+ "--resume_weights_only",
+ action="store_true",
+ help="only resume model weights",
+ )
+ parser.add_argument(
+ "-b",
+ "--base",
+ type=str,
+ default="base_config.yaml",
+ help="path to base configs",
+ )
+ parser.add_argument(
+ "-n",
+ "--name",
+ type=str,
+ default="",
+ help="experiment name",
+ )
+ parser.add_argument(
+ "--num_nodes",
+ type=int,
+ default=1,
+ help="number of nodes to use",
+ )
+ parser.add_argument(
+ "--gpus",
+ type=str,
+ default="0,",
+ help="gpu ids to use",
+ )
+ parser.add_argument(
+ "-s",
+ "--seed",
+ type=int,
+ default=42,
+ help="seed for seed_everything",
+ )
+ parser.add_argument(
+ "-l",
+ "--logdir",
+ type=str,
+ default="logs",
+ help="directory for logging data",
+ )
+ return parser
+
+
+class SetupCallback(Callback):
+ def __init__(self, resume, logdir, ckptdir, cfgdir, config):
+ super().__init__()
+ self.resume = resume
+ self.logdir = logdir
+ self.ckptdir = ckptdir
+ self.cfgdir = cfgdir
+ self.config = config
+
+ def on_fit_start(self, trainer, pl_module):
+ if trainer.global_rank == 0:
+ # Create logdirs and save configs
+ os.makedirs(self.logdir, exist_ok=True)
+ os.makedirs(self.ckptdir, exist_ok=True)
+ os.makedirs(self.cfgdir, exist_ok=True)
+
+ rank_zero_print("Project config")
+ rank_zero_print(OmegaConf.to_yaml(self.config))
+ OmegaConf.save(self.config, os.path.join(self.cfgdir, "project.yaml"))
+
+
+class CodeSnapshot(Callback):
+ """
+ Modified from https://github.com/threestudio-project/threestudio/blob/main/threestudio/utils/callbacks.py#L60
+ """
+
+ def __init__(self, savedir):
+ self.savedir = savedir
+
+ def get_file_list(self):
+ return [
+ b.decode()
+ for b in set(subprocess.check_output('git ls-files -- ":!:configs/*"', shell=True).splitlines())
+ | set( # hard code, TODO: use config to exclude folders or files
+ subprocess.check_output("git ls-files --others --exclude-standard", shell=True).splitlines()
+ )
+ ]
+
+ @rank_zero_only
+ def save_code_snapshot(self):
+ os.makedirs(self.savedir, exist_ok=True)
+
+ # for f in self.get_file_list():
+ # if not os.path.exists(f) or os.path.isdir(f):
+ # continue
+ # os.makedirs(os.path.join(self.savedir, os.path.dirname(f)), exist_ok=True)
+ # shutil.copyfile(f, os.path.join(self.savedir, f))
+
+ def on_fit_start(self, trainer, pl_module):
+ try:
+ self.save_code_snapshot()
+ except:
+ rank_zero_warn(
+ "Code snapshot is not saved. Please make sure you have git installed and are in a git repository."
+ )
+
+
+if __name__ == "__main__":
+ # add cwd for convenience and to make classes in this file available when
+ # running as `python main.py`
+ sys.path.append(os.getcwd())
+ torch.set_float32_matmul_precision("medium")
+
+ parser = get_parser()
+ opt, unknown = parser.parse_known_args()
+
+ cfg_fname = os.path.split(opt.base)[-1]
+ cfg_name = os.path.splitext(cfg_fname)[0]
+ exp_name = "-" + opt.name if opt.name != "" else ""
+ logdir = os.path.join(opt.logdir, cfg_name + exp_name)
+
+ # assert not os.path.exists(logdir) or 'test' in logdir, logdir
+ if os.path.exists(logdir) and opt.resume is None:
+ auto_resume_path = os.path.join(logdir, "checkpoints", "last.ckpt")
+ if os.path.exists(auto_resume_path):
+ opt.resume = auto_resume_path
+ print(f"Auto set resume ckpt {opt.resume}")
+
+ ckptdir = os.path.join(logdir, "checkpoints")
+ cfgdir = os.path.join(logdir, "configs")
+ codedir = os.path.join(logdir, "code")
+
+ node_rank = int(os.environ.get("NODE_RANK", 0)) # 当前节点的编号
+ local_rank = int(os.environ.get("LOCAL_RANK", 0)) # 当前节点上的 GPU 编号
+ num_gpus_per_node = torch.cuda.device_count() # 每个节点上的 GPU 数量
+
+ global_rank = node_rank * num_gpus_per_node + local_rank
+ seed_everything(opt.seed + global_rank)
+
+ # init configs
+ config = OmegaConf.load(opt.base)
+ lightning_config = config.lightning
+ trainer_config = lightning_config.trainer
+
+ trainer_config["accelerator"] = "gpu"
+ rank_zero_print(f"Running on GPUs {opt.gpus}")
+ try:
+ ngpu = int(opt.gpus)
+ except:
+ ngpu = len(opt.gpus.strip(",").split(","))
+ trainer_config["devices"] = ngpu
+
+ trainer_opt = argparse.Namespace(**trainer_config)
+ lightning_config.trainer = trainer_config
+
+ # model
+ model = instantiate_from_config(config.model)
+
+ model_unet = model.unet.unet
+ model_unet_prefix = "unet.unet."
+ if hasattr(model_unet, "unet"):
+ model_unet = model_unet.unet
+ model_unet_prefix += "unet."
+
+ if getattr(config, "init_unet_from", None):
+ unet_ckpt_path = config.init_unet_from
+ sd = torch.load(unet_ckpt_path, map_location="cpu")
+ model_unet.load_state_dict(sd, strict=True)
+
+ if getattr(config, "init_vae_from", None):
+ vae_ckpt_path = config.init_vae_from
+ sd_vae = torch.load(vae_ckpt_path, map_location="cpu")
+
+ def replace_key(key_str):
+ replace_pairs = [("key", "to_k"), ("query", "to_q"), ("value", "to_v"), ("proj_attn", "to_out.0")]
+ for replace_pair in replace_pairs:
+ key_str = key_str.replace(replace_pair[0], replace_pair[1])
+ return key_str
+
+ sd_vae = {replace_key(k): v for k, v in sd_vae.items()}
+ model.pipeline.vae.load_state_dict(sd_vae, strict=True)
+
+ if hasattr(model.unet, "controlnet"):
+ if getattr(config, "init_control_from", None):
+ unet_ckpt_path = config.init_control_from
+ sd_control = torch.load(unet_ckpt_path, map_location="cpu")
+ model.unet.controlnet.load(sd_control, strict=True)
+
+ noise_in_channels = config.model.params.get("noise_in_channels", None)
+ if noise_in_channels is not None:
+ with torch.no_grad():
+ new_conv_in = torch.nn.Conv2d(
+ noise_in_channels,
+ model_unet.conv_in.out_channels,
+ model_unet.conv_in.kernel_size,
+ model_unet.conv_in.stride,
+ model_unet.conv_in.padding,
+ )
+ new_conv_in.weight.zero_()
+ new_conv_in.weight[:, : model_unet.conv_in.in_channels, :, :].copy_(model_unet.conv_in.weight)
+
+ new_conv_in.bias.zero_()
+ new_conv_in.bias[: model_unet.conv_in.bias.size(0)].copy_(model_unet.conv_in.bias)
+
+ model_unet.conv_in = new_conv_in
+
+ if hasattr(model.unet, "controlnet"):
+ if config.model.params.get("control_in_channels", None):
+ control_in_channels = config.model.params.control_in_channels
+ model.unet.controlnet.config["conditioning_channels"] = control_in_channels
+ condition_conv_in = model.unet.controlnet.controlnet_cond_embedding.conv_in
+
+ new_condition_conv_in = torch.nn.Conv2d(
+ control_in_channels,
+ condition_conv_in.out_channels,
+ kernel_size=condition_conv_in.kernel_size,
+ stride=condition_conv_in.stride,
+ padding=condition_conv_in.padding,
+ )
+
+ with torch.no_grad():
+ new_condition_conv_in.weight[:, : condition_conv_in.in_channels, :, :] = condition_conv_in.weight
+ if condition_conv_in.bias is not None:
+ new_condition_conv_in.bias = condition_conv_in.bias
+
+ model.unet.controlnet.controlnet_cond_embedding.conv_in = new_condition_conv_in
+
+ rank_zero_print(f"Loaded Init ...")
+
+ if getattr(config, "resume_from", None):
+ cnet_ckpt_path = config.resume_from
+ sds = torch.load(cnet_ckpt_path, map_location="cpu")["state_dict"]
+ sd0 = {k[len(model_unet_prefix) :]: v for k, v in sds.items() if model_unet_prefix in k}
+ # model.unet.unet.unet.load_state_dict(sd0, strict=True)
+ model_unet.load_state_dict(sd0, strict=True)
+ if hasattr(model.unet, "controlnet"):
+ sd1 = {k[16:]: v for k, v in sds.items() if "unet.controlnet." in k}
+ model.unet.controlnet.load_state_dict(sd1, strict=True)
+ rank_zero_print(f"Loaded {cnet_ckpt_path} ...")
+
+ if opt.resume and opt.resume_weights_only:
+ model = model.__class__.load_from_checkpoint(opt.resume, **config.model.params)
+
+ model.logdir = logdir
+
+ # trainer and callbacks
+ trainer_kwargs = dict()
+
+ # logger
+ default_logger_cfg = {
+ "target": "pytorch_lightning.loggers.TensorBoardLogger",
+ "params": {
+ "name": "tensorboard",
+ "save_dir": logdir,
+ "version": "0",
+ },
+ }
+ logger_cfg = OmegaConf.merge(default_logger_cfg)
+ trainer_kwargs["logger"] = instantiate_from_config(logger_cfg)
+
+ # model checkpoint
+ default_modelckpt_cfg = {
+ "target": "pytorch_lightning.callbacks.ModelCheckpoint",
+ "params": {
+ "dirpath": ckptdir,
+ "filename": "{step:08}",
+ "verbose": True,
+ "save_last": True,
+ "every_n_train_steps": 5000,
+ "save_top_k": -1, # save all checkpoints
+ },
+ }
+
+ if "modelcheckpoint" in lightning_config:
+ modelckpt_cfg = lightning_config.modelcheckpoint
+ else:
+ modelckpt_cfg = OmegaConf.create()
+ modelckpt_cfg = OmegaConf.merge(default_modelckpt_cfg, modelckpt_cfg)
+
+ # callbacks
+ default_callbacks_cfg = {
+ "setup_callback": {
+ "target": "train.SetupCallback",
+ "params": {
+ "resume": opt.resume,
+ "logdir": logdir,
+ "ckptdir": ckptdir,
+ "cfgdir": cfgdir,
+ "config": config,
+ },
+ },
+ "learning_rate_logger": {
+ "target": "pytorch_lightning.callbacks.LearningRateMonitor",
+ "params": {
+ "logging_interval": "step",
+ },
+ },
+ "code_snapshot": {
+ "target": "train.CodeSnapshot",
+ "params": {
+ "savedir": codedir,
+ },
+ },
+ }
+ default_callbacks_cfg["checkpoint_callback"] = modelckpt_cfg
+
+ if "callbacks" in lightning_config:
+ callbacks_cfg = lightning_config.callbacks
+ else:
+ callbacks_cfg = OmegaConf.create()
+ callbacks_cfg = OmegaConf.merge(default_callbacks_cfg, callbacks_cfg)
+
+ trainer_kwargs["callbacks"] = [instantiate_from_config(callbacks_cfg[k]) for k in callbacks_cfg]
+
+ trainer_kwargs["precision"] = "bf16"
+ trainer_kwargs["strategy"] = DDPStrategy(find_unused_parameters=False)
+
+ # trainer
+ trainer = Trainer(**trainer_config, **trainer_kwargs, num_nodes=opt.num_nodes, inference_mode=False)
+ trainer.logdir = logdir
+
+ # data
+ data = instantiate_from_config(config.data)
+ data.prepare_data()
+ data.setup("fit")
+
+ # configure learning rate
+ base_lr = config.model.base_learning_rate
+ if "accumulate_grad_batches" in lightning_config.trainer:
+ accumulate_grad_batches = lightning_config.trainer.accumulate_grad_batches
+ else:
+ accumulate_grad_batches = 1
+ rank_zero_print(f"accumulate_grad_batches = {accumulate_grad_batches}")
+ lightning_config.trainer.accumulate_grad_batches = accumulate_grad_batches
+ model.learning_rate = base_lr
+ rank_zero_print("++++ NOT USING LR SCALING ++++")
+ rank_zero_print(f"Setting learning rate to {model.learning_rate:.2e}")
+
+ # run training loop
+ if opt.resume and not opt.resume_weights_only:
+ trainer.fit(model, data, ckpt_path=opt.resume)
+ else:
+ trainer.fit(model, data)
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..027da5b73aa82fe00f7f0f026cb84242e5122eb8
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..027da5b73aa82fe00f7f0f026cb84242e5122eb8
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..027da5b73aa82fe00f7f0f026cb84242e5122eb8
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/000_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f90007454795ed7d809eeccf2e444a9ba300c93
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f90007454795ed7d809eeccf2e444a9ba300c93
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f90007454795ed7d809eeccf2e444a9ba300c93
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/001_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b827233d15aedbb8df34139cdb45694818a282
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b827233d15aedbb8df34139cdb45694818a282
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b827233d15aedbb8df34139cdb45694818a282
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/002_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe4407b35b3211d3ac0f92b62618ba88ab044f14
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe4407b35b3211d3ac0f92b62618ba88ab044f14
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe4407b35b3211d3ac0f92b62618ba88ab044f14
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/003_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ac1581f380d507b446b55f3e8ac3c3511ba213f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ac1581f380d507b446b55f3e8ac3c3511ba213f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ac1581f380d507b446b55f3e8ac3c3511ba213f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/004_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..a47c7a1d86bfc9fa3ce1b1e1f15577eb695b17ad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..a47c7a1d86bfc9fa3ce1b1e1f15577eb695b17ad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..a47c7a1d86bfc9fa3ce1b1e1f15577eb695b17ad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/005_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..99f6d9a5e713add1d3bd9ce8042359f2536babbf
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..99f6d9a5e713add1d3bd9ce8042359f2536babbf
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..99f6d9a5e713add1d3bd9ce8042359f2536babbf
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/006_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7258362047240b84860ebd26b1fd2d132289244f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..7258362047240b84860ebd26b1fd2d132289244f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7258362047240b84860ebd26b1fd2d132289244f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/007_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7794eb289be59527ef95236f16ad73e899c2e8af
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..7794eb289be59527ef95236f16ad73e899c2e8af
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..7794eb289be59527ef95236f16ad73e899c2e8af
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/008_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ba4ae52ceadb0ba037505af93fdef69f1c8ca46
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ba4ae52ceadb0ba037505af93fdef69f1c8ca46
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ba4ae52ceadb0ba037505af93fdef69f1c8ca46
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/009_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..617f1f36813da1a606891afd45855c4d185138c2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..617f1f36813da1a606891afd45855c4d185138c2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..617f1f36813da1a606891afd45855c4d185138c2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/010_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..920810f826551050e94992927334e6d68475dae5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..920810f826551050e94992927334e6d68475dae5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..920810f826551050e94992927334e6d68475dae5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/011_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..544c2fda2d3237ecd0fece7d04bb9fbf19339fa2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..544c2fda2d3237ecd0fece7d04bb9fbf19339fa2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..544c2fda2d3237ecd0fece7d04bb9fbf19339fa2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/012_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4f20d720fdd0199c2ad8f26a967726f6370d5a5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4f20d720fdd0199c2ad8f26a967726f6370d5a5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4f20d720fdd0199c2ad8f26a967726f6370d5a5
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/013_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..3348fc48fbd16c852d45044a80aa7fbd286b559f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..3348fc48fbd16c852d45044a80aa7fbd286b559f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..3348fc48fbd16c852d45044a80aa7fbd286b559f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/014_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7cee4580529520ddc070b02cebda6f3f6580f76
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7cee4580529520ddc070b02cebda6f3f6580f76
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7cee4580529520ddc070b02cebda6f3f6580f76
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/015_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..08fc6cfd00ae6168107a355e051a76c37264ba00
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..08fc6cfd00ae6168107a355e051a76c37264ba00
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..08fc6cfd00ae6168107a355e051a76c37264ba00
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/016_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e57aa39b3c561cccc981149579282702035cd1a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e57aa39b3c561cccc981149579282702035cd1a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e57aa39b3c561cccc981149579282702035cd1a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/017_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb6b229f58a861eae17e35320cb0daa883b90502
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb6b229f58a861eae17e35320cb0daa883b90502
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb6b229f58a861eae17e35320cb0daa883b90502
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/018_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..0966f29f719c1159f090d9e4ea476108c769d158
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..0966f29f719c1159f090d9e4ea476108c769d158
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..0966f29f719c1159f090d9e4ea476108c769d158
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/019_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..c579532f41407268e397282122f8624f0c1f95f4
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..c579532f41407268e397282122f8624f0c1f95f4
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..c579532f41407268e397282122f8624f0c1f95f4
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/020_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..111a34128b90395ad7dfadda9d0d4b5a5c564769
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..111a34128b90395ad7dfadda9d0d4b5a5c564769
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..111a34128b90395ad7dfadda9d0d4b5a5c564769
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/021_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab721ca64063be647f900e50140e7b30e05bcbad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab721ca64063be647f900e50140e7b30e05bcbad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab721ca64063be647f900e50140e7b30e05bcbad
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/022_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_AL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_AL.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d0e08bcaf50aa45d432bb3c8d087f0e13bc2d38
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_AL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_ENVMAP.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_ENVMAP.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d0e08bcaf50aa45d432bb3c8d087f0e13bc2d38
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_ENVMAP.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_PL.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_PL.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d0e08bcaf50aa45d432bb3c8d087f0e13bc2d38
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/023_light_PL.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/mesh.ply b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/mesh.ply
new file mode 100644
index 0000000000000000000000000000000000000000..652534d9d9e977934138ab66a365db55f89b443a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/mesh.ply differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/transforms.json b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/transforms.json
new file mode 100644
index 0000000000000000000000000000000000000000..a9eae56d4335fca08a2de91bee8b97e87e7449df
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_cond/transforms.json
@@ -0,0 +1,838 @@
+{
+ "aabb": [
+ [
+ -0.5,
+ -0.5,
+ -0.5
+ ],
+ [
+ 0.5,
+ 0.5,
+ 0.5
+ ]
+ ],
+ "scale": 0.5121457915021708,
+ "offset": [
+ 0.00032189488410949707,
+ -0.03408946841955185,
+ -0.2757369577884674
+ ],
+ "frames": [
+ {
+ "file_path": "000.png",
+ "camera_angle_x": 0.47011032380678586,
+ "proj_type": 0,
+ "azimuth": 2.2539364673716054,
+ "elevation": -1.3001257577149983,
+ "cam_dis": 3.71849691615005,
+ "transform_matrix": [
+ [
+ -0.7755944728851318,
+ -0.6082496643066406,
+ -0.1687772274017334,
+ -0.6275975704193115
+ ],
+ [
+ -0.6312316656112671,
+ 0.7473564147949219,
+ 0.2073766440153122,
+ 0.7711292505264282
+ ],
+ [
+ -2.3015424233108206e-08,
+ 0.26737767457962036,
+ -0.9635918736457825,
+ -3.583113193511963
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "001.png",
+ "camera_angle_x": 0.5079176868006297,
+ "proj_type": 0,
+ "azimuth": 5.395529120961399,
+ "elevation": -0.9221878379342444,
+ "cam_dis": 3.4470348893999567,
+ "transform_matrix": [
+ [
+ 0.7755942940711975,
+ 0.5030443668365479,
+ 0.3813132345676422,
+ 1.3143998384475708
+ ],
+ [
+ 0.6312316656112671,
+ -0.6180905103683472,
+ -0.4685195982456207,
+ -1.615003228187561
+ ],
+ [
+ -4.003486608894491e-08,
+ 0.6040781140327454,
+ -0.7969250082969666,
+ -2.7470288276672363
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "002.png",
+ "camera_angle_x": 0.7090660480350758,
+ "proj_type": 0,
+ "azimuth": 3.824732794166502,
+ "elevation": -0.6818860998422269,
+ "cam_dis": 2.494654312477568,
+ "transform_matrix": [
+ [
+ 0.6312316060066223,
+ -0.4888249933719635,
+ -0.6021600961685181,
+ -1.5021814107894897
+ ],
+ [
+ -0.7755944132804871,
+ -0.39783918857574463,
+ -0.49007895588874817,
+ -1.222577691078186
+ ],
+ [
+ -2.0854262317016037e-08,
+ 0.7763853669166565,
+ -0.6302586197853088,
+ -1.5722770690917969
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "003.png",
+ "camera_angle_x": 0.7207915782104436,
+ "proj_type": 0,
+ "azimuth": 6.966325447756295,
+ "elevation": -0.48204466653151123,
+ "cam_dis": 2.4558020914544034,
+ "transform_matrix": [
+ [
+ -0.6312316060066223,
+ 0.35955917835235596,
+ 0.6872146725654602,
+ 1.687662959098816
+ ],
+ [
+ 0.7755944728851318,
+ 0.292633593082428,
+ 0.5593021512031555,
+ 1.37353515625
+ ],
+ [
+ 7.981980587601356e-08,
+ 0.8860490322113037,
+ -0.46359172463417053,
+ -1.1384897232055664
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "004.png",
+ "camera_angle_x": 1.1560563050396928,
+ "proj_type": 0,
+ "azimuth": 3.0393346307690536,
+ "elevation": -0.30147096310802857,
+ "cam_dis": 1.5850428518685533,
+ "transform_matrix": [
+ [
+ -0.10207992047071457,
+ -0.2953740656375885,
+ -0.9499125480651855,
+ -1.5056520700454712
+ ],
+ [
+ -0.99477618932724,
+ 0.03031015396118164,
+ 0.09747619181871414,
+ 0.15450391173362732
+ ],
+ [
+ 4.873770365065866e-08,
+ 0.9549007415771484,
+ -0.2969251275062561,
+ -0.47063907980918884
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "005.png",
+ "camera_angle_x": 1.1080063733527263,
+ "proj_type": 0,
+ "azimuth": 6.180927284358847,
+ "elevation": -0.13062968094200955,
+ "cam_dis": 1.6461361738590004,
+ "transform_matrix": [
+ [
+ 0.10207971930503845,
+ 0.1295779049396515,
+ 0.9863009452819824,
+ 1.6235853433609009
+ ],
+ [
+ 0.9947763085365295,
+ -0.013296757824718952,
+ -0.10121013969182968,
+ -0.16660575568675995
+ ],
+ [
+ -1.0836848218787054e-07,
+ 0.9914802312850952,
+ -0.1302584558725357,
+ -0.21442320942878723
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "006.png",
+ "camera_angle_x": 1.0631377508801954,
+ "proj_type": 0,
+ "azimuth": 4.610130957563951,
+ "elevation": 0.012136358647873546,
+ "cam_dis": 1.7085198579433762,
+ "transform_matrix": [
+ [
+ 0.99477618932724,
+ 0.0012388412142172456,
+ -0.10207240283489227,
+ -0.1743927001953125
+ ],
+ [
+ -0.10207992047071457,
+ 0.012072510085999966,
+ -0.9947029948234558,
+ -1.6994696855545044
+ ],
+ [
+ -2.03229033601815e-09,
+ 0.9999264478683472,
+ 0.012135906144976616,
+ 0.020734701305627823
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "007.png",
+ "camera_angle_x": 0.5894741433793819,
+ "proj_type": 0,
+ "azimuth": 7.751723611153743,
+ "elevation": 0.06774341874087009,
+ "cam_dis": 2.9812749570228485,
+ "transform_matrix": [
+ [
+ -0.99477618932724,
+ -0.006909956689924002,
+ 0.10184576362371445,
+ 0.30363020300865173
+ ],
+ [
+ 0.10207990556955338,
+ -0.06733796000480652,
+ 0.9924944639205933,
+ 2.9588990211486816
+ ],
+ [
+ -8.816746444040291e-09,
+ 0.9977062940597534,
+ 0.06769154965877533,
+ 0.20180732011795044
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "008.png",
+ "camera_angle_x": 1.1731446025768484,
+ "proj_type": 0,
+ "azimuth": 2.6466355490703295,
+ "elevation": 0.12356134208787495,
+ "cam_dis": 1.5646078921687379,
+ "transform_matrix": [
+ [
+ -0.47499409317970276,
+ 0.10845614224672318,
+ -0.8732801675796509,
+ -1.3663408756256104
+ ],
+ [
+ -0.8799892067909241,
+ -0.058541711419820786,
+ 0.4713726341724396,
+ 0.7375132441520691
+ ],
+ [
+ 5.2883926571212214e-08,
+ 0.9923761487007141,
+ 0.12324699014425278,
+ 0.19283349812030792
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "009.png",
+ "camera_angle_x": 0.9240898657044195,
+ "proj_type": 0,
+ "azimuth": 5.788228202660123,
+ "elevation": 0.17976943361645015,
+ "cam_dis": 1.9427212715365068,
+ "transform_matrix": [
+ [
+ 0.4749939441680908,
+ -0.15734440088272095,
+ 0.8658080101013184,
+ 1.6820236444473267
+ ],
+ [
+ 0.8799890875816345,
+ 0.08493020385503769,
+ -0.4673393964767456,
+ -0.9079101085662842
+ ],
+ [
+ -2.0080790363863343e-08,
+ 0.9838849902153015,
+ 0.17880268394947052,
+ 0.3473638594150543
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "010.png",
+ "camera_angle_x": 1.2064601116642644,
+ "proj_type": 0,
+ "azimuth": 4.217431875865226,
+ "elevation": 0.23655841484996287,
+ "cam_dis": 1.526559413456265,
+ "transform_matrix": [
+ [
+ 0.8799890875816345,
+ 0.11131872981786728,
+ -0.46176549792289734,
+ -0.7049124240875244
+ ],
+ [
+ -0.47499391436576843,
+ 0.20623266696929932,
+ -0.855481743812561,
+ -1.3059436082839966
+ ],
+ [
+ 2.947104427164504e-08,
+ 0.9721503853797913,
+ 0.23435820639133453,
+ 0.35776183009147644
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "011.png",
+ "camera_angle_x": 0.8106133703864192,
+ "proj_type": 0,
+ "azimuth": 7.359024529455018,
+ "elevation": 0.2941368085661682,
+ "cam_dis": 2.196358226678013,
+ "transform_matrix": [
+ [
+ -0.8799890875816345,
+ -0.13770732283592224,
+ 0.454594224691391,
+ 0.9984517693519592
+ ],
+ [
+ 0.47499391436576843,
+ -0.25512099266052246,
+ 0.8421959280967712,
+ 1.849764108657837
+ ],
+ [
+ -1.5272490827555885e-08,
+ 0.9570527672767639,
+ 0.2899138629436493,
+ 0.6367546319961548
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "012.png",
+ "camera_angle_x": 0.6777962932590744,
+ "proj_type": 0,
+ "azimuth": 3.4320337124677778,
+ "elevation": 0.35273892986621935,
+ "cam_dis": 2.604994196713999,
+ "transform_matrix": [
+ [
+ 0.2863747477531433,
+ 0.33100035786628723,
+ -0.8991264700889587,
+ -2.3422188758850098
+ ],
+ [
+ -0.9581177234649658,
+ 0.09893371164798737,
+ -0.2687426805496216,
+ -0.7000733017921448
+ ],
+ [
+ 5.095670019272802e-08,
+ 0.9384300708770752,
+ 0.3454693555831909,
+ 0.8999457955360413
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "013.png",
+ "camera_angle_x": 1.2201901414150222,
+ "proj_type": 0,
+ "azimuth": 6.57362636605757,
+ "elevation": 0.4126354310485474,
+ "cam_dis": 1.511532217466212,
+ "transform_matrix": [
+ [
+ -0.2863748371601105,
+ -0.38422903418540955,
+ 0.8777002096176147,
+ 1.3266719579696655
+ ],
+ [
+ 0.9581177234649658,
+ -0.11484345048666,
+ 0.2623385488986969,
+ 0.39653322100639343
+ ],
+ [
+ -1.850063036101801e-08,
+ 0.9160672426223755,
+ 0.40102484822273254,
+ 0.6061621308326721
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "014.png",
+ "camera_angle_x": 0.5705820549491503,
+ "proj_type": 0,
+ "azimuth": 5.002830039262674,
+ "elevation": 0.4741478890444091,
+ "cam_dis": 3.077158450915264,
+ "transform_matrix": [
+ [
+ 0.958117663860321,
+ -0.13075314462184906,
+ 0.2547825574874878,
+ 0.7840063571929932
+ ],
+ [
+ 0.2863748073577881,
+ 0.4374578595161438,
+ -0.8524201512336731,
+ -2.6230318546295166
+ ],
+ [
+ -1.4379679669218604e-08,
+ 0.8896821141242981,
+ 0.4565805196762085,
+ 1.4049705266952515
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "015.png",
+ "camera_angle_x": 1.1922232332059943,
+ "proj_type": 0,
+ "azimuth": 8.144422692852467,
+ "elevation": 0.5376699116109869,
+ "cam_dis": 1.5425377326560552,
+ "transform_matrix": [
+ [
+ -0.9581177234649658,
+ 0.1466628760099411,
+ -0.24596858024597168,
+ -0.3794158399105072
+ ],
+ [
+ -0.2863748371601105,
+ -0.4906865656375885,
+ 0.8229314684867859,
+ 1.2694027423858643
+ ],
+ [
+ 1.9456553701502344e-08,
+ 0.8589044213294983,
+ 0.5121359825134277,
+ 0.789989173412323
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "016.png",
+ "camera_angle_x": 0.4843348255851337,
+ "proj_type": 0,
+ "azimuth": 2.4502860082209676,
+ "elevation": 0.6036991169616068,
+ "cam_dis": 3.6113379310693747,
+ "transform_matrix": [
+ [
+ -0.6375443935394287,
+ 0.4373573660850525,
+ -0.6342363953590393,
+ -2.2904417514801025
+ ],
+ [
+ -0.7704136967658997,
+ -0.3619285523891449,
+ 0.5248528718948364,
+ 1.895421028137207
+ ],
+ [
+ 4.0876805940115446e-08,
+ 0.8232413530349731,
+ 0.5676915049552917,
+ 2.050126314163208
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "017.png",
+ "camera_angle_x": 1.0484863420149597,
+ "proj_type": 0,
+ "azimuth": 5.59187866181076,
+ "elevation": 0.6728881287032298,
+ "cam_dis": 1.7301201355596483,
+ "transform_matrix": [
+ [
+ 0.6375443935394287,
+ -0.4801580607891083,
+ 0.6024826765060425,
+ 1.0423673391342163
+ ],
+ [
+ 0.7704136371612549,
+ 0.39734768867492676,
+ -0.4985755980014801,
+ -0.8625956773757935
+ ],
+ [
+ 3.110944390982695e-09,
+ 0.7820249199867249,
+ 0.6232471466064453,
+ 1.0782924890518188
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "018.png",
+ "camera_angle_x": 0.8327046868500112,
+ "proj_type": 0,
+ "azimuth": 4.021082335015864,
+ "elevation": 0.7461309541186378,
+ "cam_dis": 2.1413633661978952,
+ "transform_matrix": [
+ [
+ 0.7704136371612549,
+ 0.432766854763031,
+ -0.46816205978393555,
+ -1.0025050640106201
+ ],
+ [
+ -0.6375443935394287,
+ 0.5229588747024536,
+ -0.5657307505607605,
+ -1.2114349603652954
+ ],
+ [
+ 2.405637644642411e-08,
+ 0.7343207597732544,
+ 0.6788026690483093,
+ 1.4535633325576782
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "019.png",
+ "camera_angle_x": 1.0378875875393918,
+ "proj_type": 0,
+ "azimuth": 7.162674988605656,
+ "elevation": 0.8247207741120075,
+ "cam_dis": 1.7461482839234206,
+ "transform_matrix": [
+ [
+ -0.7704136371612549,
+ -0.46818602085113525,
+ 0.4327409267425537,
+ 0.75562983751297
+ ],
+ [
+ 0.6375443935394287,
+ -0.5657596588134766,
+ 0.5229275226593018,
+ 0.9131090044975281
+ ],
+ [
+ 5.7037539136217674e-09,
+ 0.6787620186805725,
+ 0.7343583106994629,
+ 1.2822984457015991
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "020.png",
+ "camera_angle_x": 1.181698605034973,
+ "proj_type": 0,
+ "azimuth": 3.235684171618416,
+ "elevation": 0.9106684775229277,
+ "cam_dis": 1.5546175155141897,
+ "transform_matrix": [
+ [
+ 0.09395270049571991,
+ 0.7864198088645935,
+ -0.6105054020881653,
+ -0.9491023421287537
+ ],
+ [
+ -0.9955766797065735,
+ 0.07421454787254333,
+ -0.057613469660282135,
+ -0.08956695348024368
+ ],
+ [
+ 1.1830872281848315e-08,
+ 0.613217830657959,
+ 0.7899138331413269,
+ 1.2280138731002808
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "021.png",
+ "camera_angle_x": 1.197224930669693,
+ "proj_type": 0,
+ "azimuth": 6.377276825208208,
+ "elevation": 1.0074435322145288,
+ "cam_dis": 1.536877375373375,
+ "transform_matrix": [
+ [
+ -0.09395267069339752,
+ -0.8417297005653381,
+ 0.5316617488861084,
+ 0.81709885597229
+ ],
+ [
+ 0.9955767393112183,
+ -0.0794341042637825,
+ 0.05017295107245445,
+ 0.07710976153612137
+ ],
+ [
+ -3.2885168366192374e-08,
+ 0.5340239405632019,
+ 0.8454694151878357,
+ 1.2993828058242798
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "022.png",
+ "camera_angle_x": 0.7684080505969957,
+ "proj_type": 0,
+ "azimuth": 4.806480498413312,
+ "elevation": 1.122126648780772,
+ "cam_dis": 2.310502047946327,
+ "transform_matrix": [
+ [
+ 0.9955766797065735,
+ -0.08465376496315002,
+ 0.040753625333309174,
+ 0.09416133165359497
+ ],
+ [
+ 0.0939527377486229,
+ 0.8970394134521484,
+ -0.43184858560562134,
+ -0.9977869987487793
+ ],
+ [
+ -3.0048674659610697e-09,
+ 0.43376728892326355,
+ 0.9010249376296997,
+ 2.081820011138916
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "023.png",
+ "camera_angle_x": 1.2027037528892426,
+ "proj_type": 0,
+ "azimuth": 7.948073152003104,
+ "elevation": 1.2750349593459749,
+ "cam_dis": 1.5307354901339616,
+ "transform_matrix": [
+ [
+ -0.9955767393112183,
+ 0.08987335115671158,
+ -0.027384238317608833,
+ -0.04191803187131882
+ ],
+ [
+ -0.0939527302980423,
+ -0.9523493051528931,
+ 0.29017895460128784,
+ 0.4441872537136078
+ ],
+ [
+ -4.757865657012417e-09,
+ 0.29146820306777954,
+ 0.9565805196762085,
+ 1.4642717838287354
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000.png
new file mode 100644
index 0000000000000000000000000000000000000000..9eb7edc8109fef32e2514c5482570368d91f38f1
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..843754f1d1f8c29f7a7c9560bac367ac98aac428
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..c667cf385f4bc3e6a7d131025f6cfe0aa232f53a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..92383106e7d154b3f0d28b8b82a99e331a82f250
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..92383106e7d154b3f0d28b8b82a99e331a82f250
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..97b0f55f430cc32575a15ceb20e22423de8f3d8f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..97b0f55f430cc32575a15ceb20e22423de8f3d8f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/000_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001.png
new file mode 100644
index 0000000000000000000000000000000000000000..c471f753a5174c3e63f58452627b2bc9073fc61c
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..12fc39ae66a5ef4521814ab9d066d554d449d838
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..1137353d7a7114c14a85aa583344c80cdbe16b21
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2dee3c71550af010a901018920804510c74b7b9f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..2dee3c71550af010a901018920804510c74b7b9f
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..382c653592dbbc4b64c5a3a110655a076bc7e6f6
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..382c653592dbbc4b64c5a3a110655a076bc7e6f6
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/001_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3c120f4042eacff089a1bc4c4d3174e0dcc9c62
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..72b8b0b5f39d0438f3c718164a76d45a6efe5574
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..226c0606858c18f5c0f76527ff83009ee871a1aa
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..345552059a360fbe1557e0847607936ea7553c85
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..345552059a360fbe1557e0847607936ea7553c85
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2f03b7aaf5544a992747fdcff7a50609aeaf4f15
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f03b7aaf5544a992747fdcff7a50609aeaf4f15
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/002_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003.png
new file mode 100644
index 0000000000000000000000000000000000000000..6050552e596e80fa709978c0460dbb10b91751b0
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..84251143304eafa6b437b9f6a56fe553703c0d1c
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c54d2e0f4fd8888108b6ec4ae89129ae048315d
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e7731e9ad3b5fc77080242876227738a80c42b18
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7731e9ad3b5fc77080242876227738a80c42b18
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..095ac191515c42e6de91b31ee7c413c78a6e39b3
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..095ac191515c42e6de91b31ee7c413c78a6e39b3
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/003_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f48b693556944e7b6b8a0320d482054d403c75b
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a9c2761070597f83274cea0d33dc41aee9f012c
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ea9c88ecb770e1ec2401a2c0072a16df5bdd7f2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d1310d0d5378f63a12d11b4a72642088c849a896
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1310d0d5378f63a12d11b4a72642088c849a896
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f68c29a8b142813c9dfb0093e46c6b433d91e4c4
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..f68c29a8b142813c9dfb0093e46c6b433d91e4c4
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/004_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005.png
new file mode 100644
index 0000000000000000000000000000000000000000..2adc571790a41fe75a2056a3ee655f6f6245beea
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_albedo.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_albedo.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ab7b6022eacd599f90c3cd5b5e30e413c4d85a2
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_albedo.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_mr.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_mr.png
new file mode 100644
index 0000000000000000000000000000000000000000..29f6eee0667798f976cc758410268dd12b0b291a
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_mr.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7efd3aa87c1875f098c51941c62ab629122858bd
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..7efd3aa87c1875f098c51941c62ab629122858bd
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_normal.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.jpg b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6b05568d77a5b69ef85679f9b8c5c5869ee139e3
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.jpg differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.png b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b05568d77a5b69ef85679f9b8c5c5869ee139e3
Binary files /dev/null and b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/005_pos.png differ
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/transforms.json b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/transforms.json
new file mode 100644
index 0000000000000000000000000000000000000000..f7c46d458a00b2d44c1e4d0d03a8c4749846d979
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/train_examples/001/render_tex/transforms.json
@@ -0,0 +1,226 @@
+{
+ "aabb": [
+ [
+ -0.5,
+ -0.5,
+ -0.5
+ ],
+ [
+ 0.5,
+ 0.5,
+ 0.5
+ ]
+ ],
+ "scale": 0.5121457915021708,
+ "offset": [
+ 0.00032189488410949707,
+ -0.03408946841955185,
+ -0.2757369577884674
+ ],
+ "frames": [
+ {
+ "file_path": "000.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": -1.5707963267948966,
+ "elevation": 0,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ 1.0,
+ 0.0,
+ 6.123233601181349e-17,
+ 9.184850732644269e-17
+ ],
+ [
+ 6.123233601181349e-17,
+ 3.422854177870249e-08,
+ -0.9999999403953552,
+ -1.5
+ ],
+ [
+ 0.0,
+ 0.9999999403953552,
+ 3.422854177870249e-08,
+ 0.0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "001.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": 0,
+ "elevation": 0,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ -2.220446049250313e-16,
+ 0.0,
+ 1.0,
+ 1.5
+ ],
+ [
+ 1.0,
+ -2.220446049250313e-16,
+ 0.0,
+ 0.0
+ ],
+ [
+ 0.0,
+ 1.0,
+ -2.220446049250313e-16,
+ 0.0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "002.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": 1.5707963267948966,
+ "elevation": 0,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ -0.9999999403953552,
+ 0.0,
+ 6.123233601181349e-17,
+ 9.184850732644269e-17
+ ],
+ [
+ 6.123233601181349e-17,
+ 3.422854177870249e-08,
+ 0.9999999403953552,
+ 1.5
+ ],
+ [
+ 0.0,
+ 0.9999999403953552,
+ 3.422854177870249e-08,
+ 0.0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "003.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": 3.141592653589793,
+ "elevation": 0,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ -2.220446049250313e-16,
+ 0.0,
+ -1.0,
+ -1.5
+ ],
+ [
+ -1.0,
+ -2.220446049250313e-16,
+ 0.0,
+ 1.8369701465288538e-16
+ ],
+ [
+ 0.0,
+ 1.0,
+ -2.220446049250313e-16,
+ 0.0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "004.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": -1.5707963267948966,
+ "elevation": 1.5707963267948966,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ 1.0,
+ -6.123233601181349e-17,
+ 2.812049544789739e-33,
+ 5.624099089579478e-33
+ ],
+ [
+ 6.123233601181349e-17,
+ 1.0,
+ -3.0616171314629196e-17,
+ -9.184850732644269e-17
+ ],
+ [
+ -9.373498482632464e-34,
+ 3.0616171314629196e-17,
+ 1.0,
+ 1.5
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "file_path": "005.png",
+ "camera_angle_x": 0.9232195630055808,
+ "proj_type": 1,
+ "azimuth": -1.5707963267948966,
+ "elevation": -1.5707963267948966,
+ "cam_dis": 1.5,
+ "transform_matrix": [
+ [
+ 1.0,
+ 6.123233601181349e-17,
+ 2.812049544789739e-33,
+ 5.624099089579478e-33
+ ],
+ [
+ 6.123233601181349e-17,
+ -1.0,
+ -3.0616171314629196e-17,
+ -9.184850732644269e-17
+ ],
+ [
+ 9.373498482632464e-34,
+ 3.0616171314629196e-17,
+ -1.0,
+ -1.5
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ]
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/train_examples/examples.json b/Hunyuan3D-2.1/hy3dpaint/train_examples/examples.json
new file mode 100644
index 0000000000000000000000000000000000000000..11b519e210c18c687970a915ec98c27b02a454ab
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/train_examples/examples.json
@@ -0,0 +1,3 @@
+[
+ "hy3dpaint/train_examples/001"
+]
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/__init__.py b/Hunyuan3D-2.1/hy3dpaint/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1614ff826f65b4720649d343c43fb09dbb6b9fa5
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/__init__.py
@@ -0,0 +1,13 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/image_super_utils.py b/Hunyuan3D-2.1/hy3dpaint/utils/image_super_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d56d4f2f27990392db9d531d77b220bfab61eb3
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/image_super_utils.py
@@ -0,0 +1,41 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import numpy as np
+from PIL import Image
+
+
+class imageSuperNet:
+ def __init__(self, config) -> None:
+ from realesrgan import RealESRGANer
+ from basicsr.archs.rrdbnet_arch import RRDBNet
+
+ model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
+ upsampler = RealESRGANer(
+ scale=4,
+ model_path=config.realesrgan_ckpt_path,
+ dni_weight=None,
+ model=model,
+ tile=0,
+ tile_pad=10,
+ pre_pad=0,
+ half=True,
+ gpu_id=None,
+ )
+ self.upsampler = upsampler
+
+ def __call__(self, image):
+ output, _ = self.upsampler.enhance(np.array(image))
+ output = Image.fromarray(output)
+ return output
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/multiview_utils.py b/Hunyuan3D-2.1/hy3dpaint/utils/multiview_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..e27d6307b09ecdc7b5116b6fd2f2646705ef9cb6
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/multiview_utils.py
@@ -0,0 +1,128 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import torch
+import random
+import numpy as np
+from PIL import Image
+from typing import List
+import huggingface_hub
+from omegaconf import OmegaConf
+from diffusers import DiffusionPipeline
+from diffusers import EulerAncestralDiscreteScheduler, DDIMScheduler, UniPCMultistepScheduler
+
+
+class multiviewDiffusionNet:
+ def __init__(self, config) -> None:
+ self.device = config.device
+
+ cfg_path = config.multiview_cfg_path
+ custom_pipeline = config.custom_pipeline
+ cfg = OmegaConf.load(cfg_path)
+ self.cfg = cfg
+ self.mode = self.cfg.model.params.stable_diffusion_config.custom_pipeline[2:]
+
+ model_path = huggingface_hub.snapshot_download(
+ repo_id=config.multiview_pretrained_path,
+ allow_patterns=["hunyuan3d-paintpbr-v2-1/*"],
+ )
+
+ model_path = os.path.join(model_path, "hunyuan3d-paintpbr-v2-1")
+ pipeline = DiffusionPipeline.from_pretrained(
+ model_path,
+ custom_pipeline=custom_pipeline,
+ torch_dtype=torch.float16
+ )
+
+ pipeline.scheduler = UniPCMultistepScheduler.from_config(pipeline.scheduler.config, timestep_spacing="trailing")
+ pipeline.set_progress_bar_config(disable=True)
+ pipeline.eval()
+ setattr(pipeline, "view_size", cfg.model.params.get("view_size", 320))
+ self.pipeline = pipeline.to(self.device)
+
+ if hasattr(self.pipeline.unet, "use_dino") and self.pipeline.unet.use_dino:
+ from hunyuanpaintpbr.unet.modules import Dino_v2
+ self.dino_v2 = Dino_v2(config.dino_ckpt_path).to(torch.float16)
+ self.dino_v2 = self.dino_v2.to(self.device)
+
+ def seed_everything(self, seed):
+ random.seed(seed)
+ np.random.seed(seed)
+ torch.manual_seed(seed)
+ os.environ["PL_GLOBAL_SEED"] = str(seed)
+
+ @torch.no_grad()
+ def __call__(self, images, conditions, prompt=None, custom_view_size=None, resize_input=False):
+ pils = self.forward_one(
+ images, conditions, prompt=prompt, custom_view_size=custom_view_size, resize_input=resize_input
+ )
+ return pils
+
+ def forward_one(self, input_images, control_images, prompt=None, custom_view_size=None, resize_input=False):
+ self.seed_everything(0)
+ custom_view_size = custom_view_size if custom_view_size is not None else self.pipeline.view_size
+ if not isinstance(input_images, List):
+ input_images = [input_images]
+ if not resize_input:
+ input_images = [
+ input_image.resize((self.pipeline.view_size, self.pipeline.view_size)) for input_image in input_images
+ ]
+ else:
+ input_images = [input_image.resize((custom_view_size, custom_view_size)) for input_image in input_images]
+ for i in range(len(control_images)):
+ control_images[i] = control_images[i].resize((custom_view_size, custom_view_size))
+ if control_images[i].mode == "L":
+ control_images[i] = control_images[i].point(lambda x: 255 if x > 1 else 0, mode="1")
+ kwargs = dict(generator=torch.Generator(device=self.pipeline.device).manual_seed(0))
+
+ num_view = len(control_images) // 2
+ normal_image = [[control_images[i] for i in range(num_view)]]
+ position_image = [[control_images[i + num_view] for i in range(num_view)]]
+
+ kwargs["width"] = custom_view_size
+ kwargs["height"] = custom_view_size
+ kwargs["num_in_batch"] = num_view
+ kwargs["images_normal"] = normal_image
+ kwargs["images_position"] = position_image
+
+ if hasattr(self.pipeline.unet, "use_dino") and self.pipeline.unet.use_dino:
+ dino_hidden_states = self.dino_v2(input_images[0])
+ kwargs["dino_hidden_states"] = dino_hidden_states
+
+ sync_condition = None
+
+ infer_steps_dict = {
+ "EulerAncestralDiscreteScheduler": 30,
+ "UniPCMultistepScheduler": 15,
+ "DDIMScheduler": 50,
+ "ShiftSNRScheduler": 15,
+ }
+
+ mvd_image = self.pipeline(
+ input_images[0:1],
+ num_inference_steps=infer_steps_dict[self.pipeline.scheduler.__class__.__name__],
+ prompt=prompt,
+ sync_condition=sync_condition,
+ guidance_scale=3.0,
+ **kwargs,
+ ).images
+
+ if "pbr" in self.mode:
+ mvd_image = {"albedo": mvd_image[:num_view], "mr": mvd_image[num_view:]}
+ # mvd_image = {'albedo':mvd_image[:num_view]}
+ else:
+ mvd_image = {"hdr": mvd_image}
+
+ return mvd_image
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/pipeline_utils.py b/Hunyuan3D-2.1/hy3dpaint/utils/pipeline_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..6bc53826956211739250bc32914ce11a72809ce2
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/pipeline_utils.py
@@ -0,0 +1,135 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import torch
+import numpy as np
+
+
+class ViewProcessor:
+ def __init__(self, config, render):
+ self.config = config
+ self.render = render
+
+ def render_normal_multiview(self, camera_elevs, camera_azims, use_abs_coor=True):
+ normal_maps = []
+ for elev, azim in zip(camera_elevs, camera_azims):
+ normal_map = self.render.render_normal(elev, azim, use_abs_coor=use_abs_coor, return_type="pl")
+ normal_maps.append(normal_map)
+
+ return normal_maps
+
+ def render_position_multiview(self, camera_elevs, camera_azims):
+ position_maps = []
+ for elev, azim in zip(camera_elevs, camera_azims):
+ position_map = self.render.render_position(elev, azim, return_type="pl")
+ position_maps.append(position_map)
+
+ return position_maps
+
+ def bake_view_selection(
+ self, candidate_camera_elevs, candidate_camera_azims, candidate_view_weights, max_selected_view_num
+ ):
+
+ original_resolution = self.render.default_resolution
+ self.render.set_default_render_resolution(1024)
+
+ selected_camera_elevs = []
+ selected_camera_azims = []
+ selected_view_weights = []
+ selected_alpha_maps = []
+ viewed_tri_idxs = []
+ viewed_masks = []
+
+ # 计算每个三角片的面积
+ face_areas = self.render.get_face_areas(from_one_index=True)
+ total_area = face_areas.sum()
+ face_area_ratios = face_areas / total_area
+
+ candidate_view_num = len(candidate_camera_elevs)
+ self.render.set_boundary_unreliable_scale(2)
+
+ for elev, azim in zip(candidate_camera_elevs, candidate_camera_azims):
+ viewed_tri_idx = self.render.render_alpha(elev, azim, return_type="np")
+ viewed_tri_idxs.append(set(np.unique(viewed_tri_idx.flatten())))
+ viewed_masks.append(viewed_tri_idx[0, :, :, 0] > 0)
+
+ is_selected = [False for _ in range(candidate_view_num)]
+ total_viewed_tri_idxs = set()
+ total_viewed_area = 0.0
+
+ for idx in range(6):
+ selected_camera_elevs.append(candidate_camera_elevs[idx])
+ selected_camera_azims.append(candidate_camera_azims[idx])
+ selected_view_weights.append(candidate_view_weights[idx])
+ selected_alpha_maps.append(viewed_masks[idx])
+ is_selected[idx] = True
+ total_viewed_tri_idxs.update(viewed_tri_idxs[idx])
+
+ total_viewed_area = face_area_ratios[list(total_viewed_tri_idxs)].sum()
+ for iter in range(max_selected_view_num - len(selected_view_weights)):
+ max_inc = 0
+ max_idx = -1
+
+ for idx, (elev, azim, weight) in enumerate(
+ zip(candidate_camera_elevs, candidate_camera_azims, candidate_view_weights)
+ ):
+ if is_selected[idx]:
+ continue
+ new_tri_idxs = viewed_tri_idxs[idx] - total_viewed_tri_idxs
+ new_inc_area = face_area_ratios[list(new_tri_idxs)].sum()
+
+ if new_inc_area > max_inc:
+ max_inc = new_inc_area
+ max_idx = idx
+
+ if max_inc > 0.01:
+ is_selected[max_idx] = True
+ selected_camera_elevs.append(candidate_camera_elevs[max_idx])
+ selected_camera_azims.append(candidate_camera_azims[max_idx])
+ selected_view_weights.append(candidate_view_weights[max_idx])
+ selected_alpha_maps.append(viewed_masks[max_idx])
+ total_viewed_tri_idxs = total_viewed_tri_idxs.union(viewed_tri_idxs[max_idx])
+ total_viewed_area += max_inc
+ else:
+ break
+
+ self.render.set_default_render_resolution(original_resolution)
+
+ return selected_camera_elevs, selected_camera_azims, selected_view_weights
+
+ def bake_from_multiview(self, views, camera_elevs, camera_azims, view_weights):
+ project_textures, project_weighted_cos_maps = [], []
+ project_boundary_maps = []
+
+ for view, camera_elev, camera_azim, weight in zip(views, camera_elevs, camera_azims, view_weights):
+ project_texture, project_cos_map, project_boundary_map = self.render.back_project(
+ view, camera_elev, camera_azim
+ )
+ project_cos_map = weight * (project_cos_map**self.config.bake_exp)
+ project_textures.append(project_texture)
+ project_weighted_cos_maps.append(project_cos_map)
+ project_boundary_maps.append(project_boundary_map)
+ texture, ori_trust_map = self.render.fast_bake_texture(project_textures, project_weighted_cos_maps)
+ return texture, ori_trust_map > 1e-8
+
+ def texture_inpaint(self, texture, mask, defualt=None):
+ if defualt is not None:
+ mask = mask.astype(bool)
+ inpaint_value = torch.tensor(defualt, dtype=texture.dtype, device=texture.device)
+ texture[~mask] = inpaint_value
+ else:
+ texture_np = self.render.uv_inpaint(texture, mask)
+ texture = torch.tensor(texture_np / 255).float().to(texture.device)
+
+ return texture
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/simplify_mesh_utils.py b/Hunyuan3D-2.1/hy3dpaint/utils/simplify_mesh_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d3f10aa182c25ac4847f134a7189ab32b112054
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/simplify_mesh_utils.py
@@ -0,0 +1,37 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import trimesh
+import pymeshlab
+
+
+def remesh_mesh(mesh_path, remesh_path):
+ mesh = mesh_simplify_trimesh(mesh_path, remesh_path)
+
+
+def mesh_simplify_trimesh(inputpath, outputpath, target_count=40000):
+ # 先去除离散面
+ ms = pymeshlab.MeshSet()
+ if inputpath.endswith(".glb"):
+ ms.load_new_mesh(inputpath, load_in_a_single_layer=True)
+ else:
+ ms.load_new_mesh(inputpath)
+ ms.save_current_mesh(outputpath.replace(".glb", ".obj"), save_textures=False)
+ # 调用减面函数
+ courent = trimesh.load(outputpath.replace(".glb", ".obj"), force="mesh")
+ face_num = courent.faces.shape[0]
+
+ if face_num > target_count:
+ courent = courent.simplify_quadric_decimation(target_count)
+ courent.export(outputpath)
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/torchvision_fix.py b/Hunyuan3D-2.1/hy3dpaint/utils/torchvision_fix.py
new file mode 100644
index 0000000000000000000000000000000000000000..40cef19f218704e0b92b8119b19d29a631e579e6
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/torchvision_fix.py
@@ -0,0 +1,111 @@
+# Torchvision compatibility fix for functional_tensor module
+# This file helps resolve compatibility issues between different torchvision versions
+
+import sys
+import torch
+import torchvision
+
+def fix_torchvision_functional_tensor():
+ """
+ Fix torchvision.transforms.functional_tensor import issue
+ """
+ try:
+ # Check if the module exists in the expected location
+ import torchvision.transforms.functional_tensor
+ print("torchvision.transforms.functional_tensor is available")
+ return True
+ except ImportError:
+ print("torchvision.transforms.functional_tensor not found, applying compatibility fix...")
+
+ try:
+ # Create a mock functional_tensor module with the required functions
+ import torchvision.transforms.functional as F
+
+ class FunctionalTensorMock:
+ """Mock module to replace functional_tensor"""
+
+ @staticmethod
+ def _get_grayscale_weights(img):
+ """Helper to create grayscale weights based on image dimensions"""
+ weights = torch.tensor([0.299, 0.587, 0.114], device=img.device, dtype=img.dtype)
+ return weights.view(1, 3, 1, 1) if len(img.shape) == 4 else weights.view(3, 1, 1)
+
+ @staticmethod
+ def _try_import_fallback(module_names, attr_name):
+ """Helper to try importing from multiple modules"""
+ for module_name in module_names:
+ try:
+ module = __import__(module_name, fromlist=[attr_name])
+ if hasattr(module, attr_name):
+ return getattr(module, attr_name)
+ except ImportError:
+ continue
+ return None
+
+ @staticmethod
+ def rgb_to_grayscale(img, num_output_channels=1):
+ """Convert RGB image to grayscale"""
+ if hasattr(F, 'rgb_to_grayscale'):
+ return F.rgb_to_grayscale(img, num_output_channels)
+
+ # Fallback implementation
+ weights = FunctionalTensorMock._get_grayscale_weights(img)
+ grayscale = torch.sum(img * weights, dim=-3, keepdim=True)
+
+ if num_output_channels == 3:
+ repeat_dims = (1, 3, 1, 1) if len(img.shape) == 4 else (3, 1, 1)
+ grayscale = grayscale.repeat(*repeat_dims)
+
+ return grayscale
+
+ @staticmethod
+ def resize(img, size, interpolation=2, antialias=None):
+ """Resize function wrapper"""
+ # Try v2.functional first, then regular functional, then torch.nn.functional
+ resize_func = FunctionalTensorMock._try_import_fallback([
+ 'torchvision.transforms.v2.functional',
+ 'torchvision.transforms.functional'
+ ], 'resize')
+
+ if resize_func:
+ try:
+ return resize_func(img, size, interpolation=interpolation, antialias=antialias)
+ except TypeError:
+ # Fallback for older versions without antialias parameter
+ return resize_func(img, size, interpolation=interpolation)
+
+ # Final fallback using torch.nn.functional
+ import torch.nn.functional as torch_F
+ size = (size, size) if isinstance(size, int) else size
+ img_input = img.unsqueeze(0) if len(img.shape) == 3 else img
+ return torch_F.interpolate(img_input, size=size, mode='bilinear', align_corners=False)
+
+ def __getattr__(self, name):
+ """Fallback to regular functional module"""
+ func = self._try_import_fallback([
+ 'torchvision.transforms.functional',
+ 'torchvision.transforms.v2.functional'
+ ], name)
+
+ if func:
+ return func
+
+ raise AttributeError(f"'{name}' not found in functional_tensor mock")
+
+ # Create the mock module instance and monkey patch
+ sys.modules['torchvision.transforms.functional_tensor'] = FunctionalTensorMock()
+ print("Applied compatibility fix: created functional_tensor mock module")
+ return True
+
+ except Exception as e:
+ print(f"Failed to create functional_tensor mock: {e}")
+ return False
+
+def apply_fix():
+ """Apply the torchvision compatibility fix"""
+ print(f"Torchvision version: {torchvision.__version__}")
+ return fix_torchvision_functional_tensor()
+
+if __name__ == "__main__":
+ apply_fix()
+
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dpaint/utils/uvwrap_utils.py b/Hunyuan3D-2.1/hy3dpaint/utils/uvwrap_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..f55a924f16aa6b2dce3347f39ff7e8ef190065f4
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dpaint/utils/uvwrap_utils.py
@@ -0,0 +1,32 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import trimesh
+import xatlas
+
+
+def mesh_uv_wrap(mesh):
+ if isinstance(mesh, trimesh.Scene):
+ mesh = mesh.dump(concatenate=True)
+
+ if len(mesh.faces) > 500000000:
+ raise ValueError("The mesh has more than 500,000,000 faces, which is not supported.")
+
+ vmapping, indices, uvs = xatlas.parametrize(mesh.vertices, mesh.faces)
+
+ mesh.vertices = mesh.vertices[vmapping]
+ mesh.faces = indices
+ mesh.visual.uv = uvs
+
+ return mesh
diff --git a/Hunyuan3D-2.1/hy3dshape/.gitignore b/Hunyuan3D-2.1/hy3dshape/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..35000cb2173be759506038ac0372d2ba5177a3c8
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/.gitignore
@@ -0,0 +1,169 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+!hy3dgen/texgen/custom_rasterizer/lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# UV
+# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+#uv.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+.DS_Store
+# Cython debug symbols
+cython_debug/
+gradio_cache/
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
diff --git a/Hunyuan3D-2.1/hy3dshape/LICENSE b/Hunyuan3D-2.1/hy3dshape/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..96313b341082fb9f72a00b7c77accd8196390af0
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/LICENSE
@@ -0,0 +1,81 @@
+TENCENT HUNYUAN 3D 2.1 COMMUNITY LICENSE AGREEMENT
+Tencent Hunyuan 3D 2.1 Release Date: June 13, 2025
+THIS LICENSE AGREEMENT DOES NOT APPLY IN THE EUROPEAN UNION, UNITED KINGDOM AND SOUTH KOREA AND IS EXPRESSLY LIMITED TO THE TERRITORY, AS DEFINED BELOW.
+By clicking to agree or by using, reproducing, modifying, distributing, performing or displaying any portion or element of the Tencent Hunyuan 3D 2.1 Works, including via any Hosted Service, You will be deemed to have recognized and accepted the content of this Agreement, which is effective immediately.
+1. DEFINITIONS.
+a. “Acceptable Use Policy” shall mean the policy made available by Tencent as set forth in the Exhibit A.
+b. “Agreement” shall mean the terms and conditions for use, reproduction, distribution, modification, performance and displaying of Tencent Hunyuan 3D 2.1 Works or any portion or element thereof set forth herein.
+c. “Documentation” shall mean the specifications, manuals and documentation for Tencent Hunyuan 3D 2.1 made publicly available by Tencent.
+d. “Hosted Service” shall mean a hosted service offered via an application programming interface (API), web access, or any other electronic or remote means.
+e. “Licensee,” “You” or “Your” shall mean a natural person or legal entity exercising the rights granted by this Agreement and/or using the Tencent Hunyuan 3D 2.1 Works for any purpose and in any field of use.
+f. “Materials” shall mean, collectively, Tencent’s proprietary Tencent Hunyuan 3D 2.1 and Documentation (and any portion thereof) as made available by Tencent under this Agreement.
+g. “Model Derivatives” shall mean all: (i) modifications to Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; (ii) works based on Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1; or (iii) any other machine learning model which is created by transfer of patterns of the weights, parameters, operations, or Output of Tencent Hunyuan 3D 2.1 or any Model Derivative of Tencent Hunyuan 3D 2.1, to that model in order to cause that model to perform similarly to Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1, including distillation methods, methods that use intermediate data representations, or methods based on the generation of synthetic data Outputs by Tencent Hunyuan 3D 2.1 or a Model Derivative of Tencent Hunyuan 3D 2.1 for training that model. For clarity, Outputs by themselves are not deemed Model Derivatives.
+h. “Output” shall mean the information and/or content output of Tencent Hunyuan 3D 2.1 or a Model Derivative that results from operating or otherwise using Tencent Hunyuan 3D 2.1 or a Model Derivative, including via a Hosted Service.
+i. “Tencent,” “We” or “Us” shall mean THL Q Limited.
+j. “Tencent Hunyuan 3D 2.1” shall mean the 3D generation models and their software and algorithms, including trained model weights, parameters (including optimizer states), machine-learning model code, inference-enabling code, training-enabling code, fine-tuning enabling code and other elements of the foregoing made publicly available by Us at [ https://github.com/Tencent-Hunyuan/Hunyuan3D-2.1].
+k. “Tencent Hunyuan 3D 2.1 Works” shall mean: (i) the Materials; (ii) Model Derivatives; and (iii) all derivative works thereof.
+l. “Territory” shall mean the worldwide territory, excluding the territory of the European Union, United Kingdom and South Korea.
+m. “Third Party” or “Third Parties” shall mean individuals or legal entities that are not under common control with Us or You.
+n. “including” shall mean including but not limited to.
+2. GRANT OF RIGHTS.
+We grant You, for the Territory only, a non-exclusive, non-transferable and royalty-free limited license under Tencent’s intellectual property or other rights owned by Us embodied in or utilized by the Materials to use, reproduce, distribute, create derivative works of (including Model Derivatives), and make modifications to the Materials, only in accordance with the terms of this Agreement and the Acceptable Use Policy, and You must not violate (or encourage or permit anyone else to violate) any term of this Agreement or the Acceptable Use Policy.
+3. DISTRIBUTION.
+You may, subject to Your compliance with this Agreement, distribute or make available to Third Parties the Tencent Hunyuan 3D 2.1 Works, exclusively in the Territory, provided that You meet all of the following conditions:
+a. You must provide all such Third Party recipients of the Tencent Hunyuan 3D 2.1 Works or products or services using them a copy of this Agreement;
+b. You must cause any modified files to carry prominent notices stating that You changed the files;
+c. You are encouraged to: (i) publish at least one technology introduction blogpost or one public statement expressing Your experience of using the Tencent Hunyuan 3D 2.1 Works; and (ii) mark the products or services developed by using the Tencent Hunyuan 3D 2.1 Works to indicate that the product/service is “Powered by Tencent Hunyuan”; and
+d. All distributions to Third Parties (other than through a Hosted Service) must be accompanied by a “Notice” text file that contains the following notice: “Tencent Hunyuan 3D 2.1 is licensed under the Tencent Hunyuan 3D 2.1 Community License Agreement, Copyright © 2025 Tencent. All Rights Reserved. The trademark rights of “Tencent Hunyuan” are owned by Tencent or its affiliate.”
+You may add Your own copyright statement to Your modifications and, except as set forth in this Section and in Section 5, may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Model Derivatives as a whole, provided Your use, reproduction, modification, distribution, performance and display of the work otherwise complies with the terms and conditions of this Agreement (including as regards the Territory). If You receive Tencent Hunyuan 3D 2.1 Works from a Licensee as part of an integrated end user product, then this Section 3 of this Agreement will not apply to You.
+4. ADDITIONAL COMMERCIAL TERMS.
+If, on the Tencent Hunyuan 3D 2.1 version release date, the monthly active users of all products or services made available by or for Licensee is greater than 1 million monthly active users in the preceding calendar month, You must request a license from Tencent, which Tencent may grant to You in its sole discretion, and You are not authorized to exercise any of the rights under this Agreement unless or until Tencent otherwise expressly grants You such rights.
+Subject to Tencent's written approval, you may request a license for the use of Tencent Hunyuan 3D 2.1 by submitting the following information to hunyuan3d@tencent.com:
+a. Your company’s name and associated business sector that plans to use Tencent Hunyuan 3D 2.1.
+b. Your intended use case and the purpose of using Tencent Hunyuan 3D 2.1.
+c. Your plans to modify Tencent Hunyuan 3D 2.1 or create Model Derivatives.
+5. RULES OF USE.
+a. Your use of the Tencent Hunyuan 3D 2.1 Works must comply with applicable laws and regulations (including trade compliance laws and regulations) and adhere to the Acceptable Use Policy for the Tencent Hunyuan 3D 2.1 Works, which is hereby incorporated by reference into this Agreement. You must include the use restrictions referenced in these Sections 5(a) and 5(b) as an enforceable provision in any agreement (e.g., license agreement, terms of use, etc.) governing the use and/or distribution of Tencent Hunyuan 3D 2.1 Works and You must provide notice to subsequent users to whom You distribute that Tencent Hunyuan 3D 2.1 Works are subject to the use restrictions in these Sections 5(a) and 5(b).
+b. You must not use the Tencent Hunyuan 3D 2.1 Works or any Output or results of the Tencent Hunyuan 3D 2.1 Works to improve any other AI model (other than Tencent Hunyuan 3D 2.1 or Model Derivatives thereof).
+c. You must not use, reproduce, modify, distribute, or display the Tencent Hunyuan 3D 2.1 Works, Output or results of the Tencent Hunyuan 3D 2.1 Works outside the Territory. Any such use outside the Territory is unlicensed and unauthorized under this Agreement.
+6. INTELLECTUAL PROPERTY.
+a. Subject to Tencent’s ownership of Tencent Hunyuan 3D 2.1 Works made by or for Tencent and intellectual property rights therein, conditioned upon Your compliance with the terms and conditions of this Agreement, as between You and Tencent, You will be the owner of any derivative works and modifications of the Materials and any Model Derivatives that are made by or for You.
+b. No trademark licenses are granted under this Agreement, and in connection with the Tencent Hunyuan 3D 2.1 Works, Licensee may not use any name or mark owned by or associated with Tencent or any of its affiliates, except as required for reasonable and customary use in describing and distributing the Tencent Hunyuan 3D 2.1 Works. Tencent hereby grants You a license to use “Tencent Hunyuan” (the “Mark”) in the Territory solely as required to comply with the provisions of Section 3(c), provided that You comply with any applicable laws related to trademark protection. All goodwill arising out of Your use of the Mark will inure to the benefit of Tencent.
+c. If You commence a lawsuit or other proceedings (including a cross-claim or counterclaim in a lawsuit) against Us or any person or entity alleging that the Materials or any Output, or any portion of any of the foregoing, infringe any intellectual property or other right owned or licensable by You, then all licenses granted to You under this Agreement shall terminate as of the date such lawsuit or other proceeding is filed. You will defend, indemnify and hold harmless Us from and against any claim by any Third Party arising out of or related to Your or the Third Party’s use or distribution of the Tencent Hunyuan 3D 2.1 Works.
+d. Tencent claims no rights in Outputs You generate. You and Your users are solely responsible for Outputs and their subsequent uses.
+7. DISCLAIMERS OF WARRANTY AND LIMITATIONS OF LIABILITY.
+a. We are not obligated to support, update, provide training for, or develop any further version of the Tencent Hunyuan 3D 2.1 Works or to grant any license thereto.
+b. UNLESS AND ONLY TO THE EXTENT REQUIRED BY APPLICABLE LAW, THE TENCENT HUNYUAN 3D 2.1 WORKS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND INCLUDING ANY WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, COURSE OF DEALING, USAGE OF TRADE, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING, REPRODUCING, MODIFYING, PERFORMING, DISPLAYING OR DISTRIBUTING ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND ASSUME ANY AND ALL RISKS ASSOCIATED WITH YOUR OR A THIRD PARTY’S USE OR DISTRIBUTION OF ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS AND YOUR EXERCISE OF RIGHTS AND PERMISSIONS UNDER THIS AGREEMENT.
+c. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL TENCENT OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, FOR ANY DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, CONSEQUENTIAL OR PUNITIVE DAMAGES, OR LOST PROFITS OF ANY KIND ARISING FROM THIS AGREEMENT OR RELATED TO ANY OF THE TENCENT HUNYUAN 3D 2.1 WORKS OR OUTPUTS, EVEN IF TENCENT OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING.
+8. SURVIVAL AND TERMINATION.
+a. The term of this Agreement shall commence upon Your acceptance of this Agreement or access to the Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein.
+b. We may terminate this Agreement if You breach any of the terms or conditions of this Agreement. Upon termination of this Agreement, You must promptly delete and cease use of the Tencent Hunyuan 3D 2.1 Works. Sections 6(a), 6(c), 7 and 9 shall survive the termination of this Agreement.
+9. GOVERNING LAW AND JURISDICTION.
+a. This Agreement and any dispute arising out of or relating to it will be governed by the laws of the Hong Kong Special Administrative Region of the People’s Republic of China, without regard to conflict of law principles, and the UN Convention on Contracts for the International Sale of Goods does not apply to this Agreement.
+b. Exclusive jurisdiction and venue for any dispute arising out of or relating to this Agreement will be a court of competent jurisdiction in the Hong Kong Special Administrative Region of the People’s Republic of China, and Tencent and Licensee consent to the exclusive jurisdiction of such court with respect to any such dispute.
+
+EXHIBIT A
+ACCEPTABLE USE POLICY
+
+Tencent reserves the right to update this Acceptable Use Policy from time to time.
+Last modified: November 5, 2024
+
+Tencent endeavors to promote safe and fair use of its tools and features, including Tencent Hunyuan 3D 2.1. You agree not to use Tencent Hunyuan 3D 2.1 or Model Derivatives:
+1. Outside the Territory;
+2. In any way that violates any applicable national, federal, state, local, international or any other law or regulation;
+3. To harm Yourself or others;
+4. To repurpose or distribute output from Tencent Hunyuan 3D 2.1 or any Model Derivatives to harm Yourself or others;
+5. To override or circumvent the safety guardrails and safeguards We have put in place;
+6. For the purpose of exploiting, harming or attempting to exploit or harm minors in any way;
+7. To generate or disseminate verifiably false information and/or content with the purpose of harming others or influencing elections;
+8. To generate or facilitate false online engagement, including fake reviews and other means of fake online engagement;
+9. To intentionally defame, disparage or otherwise harass others;
+10. To generate and/or disseminate malware (including ransomware) or any other content to be used for the purpose of harming electronic systems;
+11. To generate or disseminate personal identifiable information with the purpose of harming others;
+12. To generate or disseminate information (including images, code, posts, articles), and place the information in any public context (including –through the use of bot generated tweets), without expressly and conspicuously identifying that the information and/or content is machine generated;
+13. To impersonate another individual without consent, authorization, or legal right;
+14. To make high-stakes automated decisions in domains that affect an individual’s safety, rights or wellbeing (e.g., law enforcement, migration, medicine/health, management of critical infrastructure, safety components of products, essential services, credit, employment, housing, education, social scoring, or insurance);
+15. In a manner that violates or disrespects the social ethics and moral standards of other countries or regions;
+16. To perform, facilitate, threaten, incite, plan, promote or encourage violent extremism or terrorism;
+17. For any use intended to discriminate against or harm individuals or groups based on protected characteristics or categories, online or offline social behavior or known or predicted personal or personality characteristics;
+18. To intentionally exploit any of the vulnerabilities of a specific group of persons based on their age, social, physical or mental characteristics, in order to materially distort the behavior of a person pertaining to that group in a manner that causes or is likely to cause that person or another person physical or psychological harm;
+19. For military purposes;
+20. To engage in the unauthorized or unlicensed practice of any profession including, but not limited to, financial, legal, medical/health, or other professional practices.
diff --git a/Hunyuan3D-2.1/hy3dshape/NOTICE b/Hunyuan3D-2.1/hy3dshape/NOTICE
new file mode 100644
index 0000000000000000000000000000000000000000..e02234d9704824b109ffe3625aa9b8b94dad2d55
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/NOTICE
@@ -0,0 +1,214 @@
+Usage and Legal Notices:
+
+Tencent is pleased to support the open source community by making Hunyuan 3D 2.0 available.
+
+Copyright (C) 2025 THL A29 Limited, a Tencent company. All rights reserved. The below software and/or models in this distribution may have been modified by THL A29 Limited ("Tencent Modifications"). All Tencent Modifications are Copyright (C) THL A29 Limited.
+
+Hunyuan 3D 2.0 is licensed under the TENCENT HUNYUAN 3D 2.0 COMMUNITY LICENSE AGREEMENT except for the third-party components listed below, which is licensed under different terms. Hunyuan 3D 2.0 does not impose any additional limitations beyond what is outlined in the respective licenses of these third-party components. Users must comply with all terms and conditions of original licenses of these third-party components and must ensure that the usage of the third party components adheres to all relevant laws and regulations.
+
+For avoidance of doubts, Hunyuan 3D 2.0 means inference-enabling code, parameters, and weights of this Model only, which are made publicly available by Tencent in accordance with TENCENT HUNYUAN 3D 2.0 COMMUNITY LICENSE AGREEMENT.
+
+
+Other dependencies and licenses:
+
+
+Open Source Model Licensed under the MIT and CreativeML Open RAIL++-M License:
+--------------------------------------------------------------------
+1. Stable Diffusion
+Copyright (c) 2022 Stability AI
+
+
+Terms of the MIT and CreativeML Open RAIL++-M License:
+--------------------------------------------------------------------
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+CreativeML Open RAIL++-M License
+dated November 24, 2022
+
+Section I: PREAMBLE
+
+Multimodal generative models are being widely adopted and used, and have the potential to transform the way artists, among other individuals, conceive and benefit from AI or ML technologies as a tool for content creation.
+
+Notwithstanding the current and potential benefits that these artifacts can bring to society at large, there are also concerns about potential misuses of them, either due to their technical limitations or ethical considerations.
+
+In short, this license strives for both the open and responsible downstream use of the accompanying model. When it comes to the open character, we took inspiration from open source permissive licenses regarding the grant of IP rights. Referring to the downstream responsible use, we added use-based restrictions not permitting the use of the Model in very specific scenarios, in order for the licensor to be able to enforce the license in case potential misuses of the Model may occur. At the same time, we strive to promote open and responsible research on generative models for art and content generation.
+
+Even though downstream derivative versions of the model could be released under different licensing terms, the latter will always have to include - at minimum - the same use-based restrictions as the ones in the original license (this license). We believe in the intersection between open and responsible AI development; thus, this License aims to strike a balance between both in order to enable responsible open-science in the field of AI.
+
+This License governs the use of the model (and its derivatives) and is informed by the model card associated with the model.
+
+NOW THEREFORE, You and Licensor agree as follows:
+
+1. Definitions
+
+- "License" means the terms and conditions for use, reproduction, and Distribution as defined in this document.
+- "Data" means a collection of information and/or content extracted from the dataset used with the Model, including to train, pretrain, or otherwise evaluate the Model. The Data is not licensed under this License.
+- "Output" means the results of operating a Model as embodied in informational content resulting therefrom.
+- "Model" means any accompanying machine-learning based assemblies (including checkpoints), consisting of learnt weights, parameters (including optimizer states), corresponding to the model architecture as embodied in the Complementary Material, that have been trained or tuned, in whole or in part on the Data, using the Complementary Material.
+- "Derivatives of the Model" means all modifications to the Model, works based on the Model, or any other model which is created or initialized by transfer of patterns of the weights, parameters, activations or output of the Model, to the other model, in order to cause the other model to perform similarly to the Model, including - but not limited to - distillation methods entailing the use of intermediate data representations or methods based on the generation of synthetic data by the Model for training the other model.
+- "Complementary Material" means the accompanying source code and scripts used to define, run, load, benchmark or evaluate the Model, and used to prepare data for training or evaluation, if any. This includes any accompanying documentation, tutorials, examples, etc, if any.
+- "Distribution" means any transmission, reproduction, publication or other sharing of the Model or Derivatives of the Model to a third party, including providing the Model as a hosted service made available by electronic or other remote means - e.g. API-based or web access.
+- "Licensor" means the copyright owner or entity authorized by the copyright owner that is granting the License, including the persons or entities that may have rights in the Model and/or distributing the Model.
+- "You" (or "Your") means an individual or Legal Entity exercising permissions granted by this License and/or making use of the Model for whichever purpose and in any field of use, including usage of the Model in an end-use application - e.g. chatbot, translator, image generator.
+- "Third Parties" means individuals or legal entities that are not under common control with Licensor or You.
+- "Contribution" means any work of authorship, including the original version of the Model and any modifications or additions to that Model or Derivatives of the Model thereof, that is intentionally submitted to Licensor for inclusion in the Model by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Model, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+- "Contributor" means Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Model.
+
+Section II: INTELLECTUAL PROPERTY RIGHTS
+
+Both copyright and patent grants apply to the Model, Derivatives of the Model and Complementary Material. The Model and Derivatives of the Model are subject to additional terms as described in Section III.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare, publicly display, publicly perform, sublicense, and distribute the Complementary Material, the Model, and Derivatives of the Model.
+3. Grant of Patent License. Subject to the terms and conditions of this License and where and as applicable, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this paragraph) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Model and the Complementary Material, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Model to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Model and/or Complementary Material or a Contribution incorporated within the Model and/or Complementary Material constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for the Model and/or Work shall terminate as of the date such litigation is asserted or filed.
+
+Section III: CONDITIONS OF USAGE, DISTRIBUTION AND REDISTRIBUTION
+
+4. Distribution and Redistribution. You may host for Third Party remote access purposes (e.g. software-as-a-service), reproduce and distribute copies of the Model or Derivatives of the Model thereof in any medium, with or without modifications, provided that You meet the following conditions:
+Use-based restrictions as referenced in paragraph 5 MUST be included as an enforceable provision by You in any type of legal agreement (e.g. a license) governing the use and/or distribution of the Model or Derivatives of the Model, and You shall give notice to subsequent users You Distribute to, that the Model or Derivatives of the Model are subject to paragraph 5. This provision does not apply to the use of Complementary Material.
+You must give any Third Party recipients of the Model or Derivatives of the Model a copy of this License;
+You must cause any modified files to carry prominent notices stating that You changed the files;
+You must retain all copyright, patent, trademark, and attribution notices excluding those notices that do not pertain to any part of the Model, Derivatives of the Model.
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions - respecting paragraph 4.a. - for use, reproduction, or Distribution of Your modifications, or for any such Derivatives of the Model as a whole, provided Your use, reproduction, and Distribution of the Model otherwise complies with the conditions stated in this License.
+5. Use-based restrictions. The restrictions set forth in Attachment A are considered Use-based restrictions. Therefore You cannot use the Model and the Derivatives of the Model for the specified restricted uses. You may use the Model subject to this License, including only for lawful purposes and in accordance with the License. Use may include creating any content with, finetuning, updating, running, training, evaluating and/or reparametrizing the Model. You shall require all of Your users who use the Model or a Derivative of the Model to comply with the terms of this paragraph (paragraph 5).
+6. The Output You Generate. Except as set forth herein, Licensor claims no rights in the Output You generate using the Model. You are accountable for the Output you generate and its subsequent uses. No use of the output can contravene any provision as stated in the License.
+
+Section IV: OTHER PROVISIONS
+
+7. Updates and Runtime Restrictions. To the maximum extent permitted by law, Licensor reserves the right to restrict (remotely or otherwise) usage of the Model in violation of this License.
+8. Trademarks and related. Nothing in this License permits You to make use of Licensors’ trademarks, trade names, logos or to otherwise suggest endorsement or misrepresent the relationship between the parties; and any rights not expressly granted herein are reserved by the Licensors.
+9. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Model and the Complementary Material (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Model, Derivatives of the Model, and the Complementary Material and assume any risks associated with Your exercise of permissions under this License.
+10. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Model and the Complementary Material (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+11. Accepting Warranty or Additional Liability. While redistributing the Model, Derivatives of the Model and the Complementary Material thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+12. If any provision of this License is held to be invalid, illegal or unenforceable, the remaining provisions shall be unaffected thereby and remain valid as if such provision had not been set forth herein.
+
+END OF TERMS AND CONDITIONS
+
+
+
+
+Attachment A
+
+Use Restrictions
+
+You agree not to use the Model or Derivatives of the Model:
+
+- In any way that violates any applicable national, federal, state, local or international law or regulation;
+- For the purpose of exploiting, harming or attempting to exploit or harm minors in any way;
+- To generate or disseminate verifiably false information and/or content with the purpose of harming others;
+- To generate or disseminate personal identifiable information that can be used to harm an individual;
+- To defame, disparage or otherwise harass others;
+- For fully automated decision making that adversely impacts an individual’s legal rights or otherwise creates or modifies a binding, enforceable obligation;
+- For any use intended to or which has the effect of discriminating against or harming individuals or groups based on online or offline social behavior or known or predicted personal or personality characteristics;
+- To exploit any of the vulnerabilities of a specific group of persons based on their age, social, physical or mental characteristics, in order to materially distort the behavior of a person pertaining to that group in a manner that causes or is likely to cause that person or another person physical or psychological harm;
+- For any use intended to or which has the effect of discriminating against individuals or groups based on legally protected characteristics or categories;
+- To provide medical advice and medical results interpretation;
+- To generate or disseminate information for the purpose to be used for administration of justice, law enforcement, immigration or asylum processes, such as predicting an individual will commit fraud/crime commitment (e.g. by text profiling, drawing causal relationships between assertions made in documents, indiscriminate and arbitrarily-targeted use).
+
+
+
+Open Source Model Licensed under the TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT and Other Licenses of the Third-Party Components therein:
+--------------------------------------------------------------------
+1. HunyuanDiT
+Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
+
+
+Terms of the TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT:
+--------------------------------------------------------------------
+TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT
+Tencent Hunyuan Release Date: 2024/5/14
+By clicking to agree or by using, reproducing, modifying, distributing, performing or displaying any portion or element of the Tencent Hunyuan Works, including via any Hosted Service, You will be deemed to have recognized and accepted the content of this Agreement, which is effective immediately.
+1. DEFINITIONS.
+a. “Acceptable Use Policy” shall mean the policy made available by Tencent as set forth in the Exhibit A.
+b. “Agreement” shall mean the terms and conditions for use, reproduction, distribution, modification, performance and displaying of the Hunyuan Works or any portion or element thereof set forth herein.
+c. “Documentation” shall mean the specifications, manuals and documentation for Tencent Hunyuan made publicly available by Tencent.
+d. “Hosted Service” shall mean a hosted service offered via an application programming interface (API), web access, or any other electronic or remote means.
+e. “Licensee,” “You” or “Your” shall mean a natural person or legal entity exercising the rights granted by this Agreement and/or using the Tencent Hunyuan Works for any purpose and in any field of use.
+f. “Materials” shall mean, collectively, Tencent’s proprietary Tencent Hunyuan and Documentation (and any portion thereof) as made available by Tencent under this Agreement.
+g. “Model Derivatives” shall mean all: (i) modifications to Tencent Hunyuan or any Model Derivative of Tencent Hunyuan; (ii) works based on Tencent Hunyuan or any Model Derivative of Tencent Hunyuan; or (iii) any other machine learning model which is created by transfer of patterns of the weights, parameters, operations, or Output of Tencent Hunyuan or any Model Derivative of Tencent Hunyuan, to that model in order to cause that model to perform similarly to Tencent Hunyuan or a Model Derivative of Tencent Hunyuan, including distillation methods, methods that use intermediate data representations, or methods based on the generation of synthetic data Outputs by Tencent Hunyuan or a Model Derivative of Tencent Hunyuan for training that model. For clarity, Outputs by themselves are not deemed Model Derivatives.
+h. “Output” shall mean the information and/or content output of Tencent Hunyuan or a Model Derivative that results from operating or otherwise using Tencent Hunyuan or a Model Derivative, including via a Hosted Service.
+i. “Tencent,” “We” or “Us” shall mean THL A29 Limited.
+j. “Tencent Hunyuan” shall mean the large language models, image/video/audio/3D generation models, and multimodal large language models and their software and algorithms, including trained model weights, parameters (including optimizer states), machine-learning model code, inference-enabling code, training-enabling code, fine-tuning enabling code and other elements of the foregoing made publicly available by Us at https://huggingface.co/Tencent-Hunyuan/HunyuanDiT and https://github.com/Tencent/HunyuanDiT .
+k. “Tencent Hunyuan Works” shall mean: (i) the Materials; (ii) Model Derivatives; and (iii) all derivative works thereof.
+l. “Third Party” or “Third Parties” shall mean individuals or legal entities that are not under common control with Us or You.
+m. “including” shall mean including but not limited to.
+2. GRANT OF RIGHTS.
+We grant You a non-exclusive, worldwide, non-transferable and royalty-free limited license under Tencent’s intellectual property or other rights owned by Us embodied in or utilized by the Materials to use, reproduce, distribute, create derivative works of (including Model Derivatives), and make modifications to the Materials, only in accordance with the terms of this Agreement and the Acceptable Use Policy, and You must not violate (or encourage or permit anyone else to violate) any term of this Agreement or the Acceptable Use Policy.
+3. DISTRIBUTION.
+You may, subject to Your compliance with this Agreement, distribute or make available to Third Parties the Tencent Hunyuan Works, provided that You meet all of the following conditions:
+a. You must provide all such Third Party recipients of the Tencent Hunyuan Works or products or services using them a copy of this Agreement;
+b. You must cause any modified files to carry prominent notices stating that You changed the files;
+c. You are encouraged to: (i) publish at least one technology introduction blogpost or one public statement expressing Your experience of using the Tencent Hunyuan Works; and (ii) mark the products or services developed by using the Tencent Hunyuan Works to indicate that the product/service is “Powered by Tencent Hunyuan”; and
+d. All distributions to Third Parties (other than through a Hosted Service) must be accompanied by a “Notice” text file that contains the following notice: “Tencent Hunyuan is licensed under the Tencent Hunyuan Community License Agreement, Copyright © 2024 Tencent. All Rights Reserved. The trademark rights of “Tencent Hunyuan” are owned by Tencent or its affiliate.”
+You may add Your own copyright statement to Your modifications and, except as set forth in this Section and in Section 5, may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Model Derivatives as a whole, provided Your use, reproduction, modification, distribution, performance and display of the work otherwise complies with the terms and conditions of this Agreement. If You receive Tencent Hunyuan Works from a Licensee as part of an integrated end user product, then this Section 3 of this Agreement will not apply to You.
+4. ADDITIONAL COMMERCIAL TERMS.
+If, on the Tencent Hunyuan version release date, the monthly active users of all products or services made available by or for Licensee is greater than 100 million monthly active users in the preceding calendar month, You must request a license from Tencent, which Tencent may grant to You in its sole discretion, and You are not authorized to exercise any of the rights under this Agreement unless or until Tencent otherwise expressly grants You such rights.
+5. RULES OF USE.
+a. Your use of the Tencent Hunyuan Works must comply with applicable laws and regulations (including trade compliance laws and regulations) and adhere to the Acceptable Use Policy for the Tencent Hunyuan Works, which is hereby incorporated by reference into this Agreement. You must include the use restrictions referenced in these Sections 5(a) and 5(b) as an enforceable provision in any agreement (e.g., license agreement, terms of use, etc.) governing the use and/or distribution of Tencent Hunyuan Works and You must provide notice to subsequent users to whom You distribute that Tencent Hunyuan Works are subject to the use restrictions in these Sections 5(a) and 5(b).
+b. You must not use the Tencent Hunyuan Works or any Output or results of the Tencent Hunyuan Works to improve any other large language model (other than Tencent Hunyuan or Model Derivatives thereof).
+6. INTELLECTUAL PROPERTY.
+a. Subject to Tencent’s ownership of Tencent Hunyuan Works made by or for Tencent and intellectual property rights therein, conditioned upon Your compliance with the terms and conditions of this Agreement, as between You and Tencent, You will be the owner of any derivative works and modifications of the Materials and any Model Derivatives that are made by or for You.
+b. No trademark licenses are granted under this Agreement, and in connection with the Tencent Hunyuan Works, Licensee may not use any name or mark owned by or associated with Tencent or any of its affiliates, except as required for reasonable and customary use in describing and distributing the Tencent Hunyuan Works. Tencent hereby grants You a license to use “Tencent Hunyuan” (the “Mark”) solely as required to comply with the provisions of Section 3(c), provided that You comply with any applicable laws related to trademark protection. All goodwill arising out of Your use of the Mark will inure to the benefit of Tencent.
+c. If You commence a lawsuit or other proceedings (including a cross-claim or counterclaim in a lawsuit) against Us or any person or entity alleging that the Materials or any Output, or any portion of any of the foregoing, infringe any intellectual property or other right owned or licensable by You, then all licenses granted to You under this Agreement shall terminate as of the date such lawsuit or other proceeding is filed. You will defend, indemnify and hold harmless Us from and against any claim by any Third Party arising out of or related to Your or the Third Party’s use or distribution of the Tencent Hunyuan Works.
+d. Tencent claims no rights in Outputs You generate. You and Your users are solely responsible for Outputs and their subsequent uses.
+7. DISCLAIMERS OF WARRANTY AND LIMITATIONS OF LIABILITY.
+a. We are not obligated to support, update, provide training for, or develop any further version of the Tencent Hunyuan Works or to grant any license thereto.
+b. UNLESS AND ONLY TO THE EXTENT REQUIRED BY APPLICABLE LAW, THE TENCENT HUNYUAN WORKS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND INCLUDING ANY WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, COURSE OF DEALING, USAGE OF TRADE, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING, REPRODUCING, MODIFYING, PERFORMING, DISPLAYING OR DISTRIBUTING ANY OF THE TENCENT HUNYUAN WORKS OR OUTPUTS AND ASSUME ANY AND ALL RISKS ASSOCIATED WITH YOUR OR A THIRD PARTY’S USE OR DISTRIBUTION OF ANY OF THE TENCENT HUNYUAN WORKS OR OUTPUTS AND YOUR EXERCISE OF RIGHTS AND PERMISSIONS UNDER THIS AGREEMENT.
+c. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL TENCENT OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, FOR ANY DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, CONSEQUENTIAL OR PUNITIVE DAMAGES, OR LOST PROFITS OF ANY KIND ARISING FROM THIS AGREEMENT OR RELATED TO ANY OF THE TENCENT HUNYUAN WORKS OR OUTPUTS, EVEN IF TENCENT OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING.
+8. SURVIVAL AND TERMINATION.
+a. The term of this Agreement shall commence upon Your acceptance of this Agreement or access to the Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein.
+b. We may terminate this Agreement if You breach any of the terms or conditions of this Agreement. Upon termination of this Agreement, You must promptly delete and cease use of the Tencent Hunyuan Works. Sections 6(a), 6(c), 7 and 9 shall survive the termination of this Agreement.
+9. GOVERNING LAW AND JURISDICTION.
+a. This Agreement and any dispute arising out of or relating to it will be governed by the laws of the Hong Kong Special Administrative Region of the People’s Republic of China, without regard to conflict of law principles, and the UN Convention on Contracts for the International Sale of Goods does not apply to this Agreement.
+b. Exclusive jurisdiction and venue for any dispute arising out of or relating to this Agreement will be a court of competent jurisdiction in the Hong Kong Special Administrative Region of the People’s Republic of China, and Tencent and Licensee consent to the exclusive jurisdiction of such court with respect to any such dispute.
+
+
+EXHIBIT A
+ACCEPTABLE USE POLICY
+
+Tencent reserves the right to update this Acceptable Use Policy from time to time.
+Last modified: 2024/5/14
+
+Tencent endeavors to promote safe and fair use of its tools and features, including Tencent Hunyuan. You agree not to use Tencent Hunyuan or Model Derivatives:
+1. In any way that violates any applicable national, federal, state, local, international or any other law or regulation;
+2. To harm Yourself or others;
+3. To repurpose or distribute output from Tencent Hunyuan or any Model Derivatives to harm Yourself or others;
+4. To override or circumvent the safety guardrails and safeguards We have put in place;
+5. For the purpose of exploiting, harming or attempting to exploit or harm minors in any way;
+6. To generate or disseminate verifiably false information and/or content with the purpose of harming others or influencing elections;
+7. To generate or facilitate false online engagement, including fake reviews and other means of fake online engagement;
+8. To intentionally defame, disparage or otherwise harass others;
+9. To generate and/or disseminate malware (including ransomware) or any other content to be used for the purpose of harming electronic systems;
+10. To generate or disseminate personal identifiable information with the purpose of harming others;
+11. To generate or disseminate information (including images, code, posts, articles), and place the information in any public context (including –through the use of bot generated tweets), without expressly and conspicuously identifying that the information and/or content is machine generated;
+12. To impersonate another individual without consent, authorization, or legal right;
+13. To make high-stakes automated decisions in domains that affect an individual’s safety, rights or wellbeing (e.g., law enforcement, migration, medicine/health, management of critical infrastructure, safety components of products, essential services, credit, employment, housing, education, social scoring, or insurance);
+14. In a manner that violates or disrespects the social ethics and moral standards of other countries or regions;
+15. To perform, facilitate, threaten, incite, plan, promote or encourage violent extremism or terrorism;
+16. For any use intended to discriminate against or harm individuals or groups based on protected characteristics or categories, online or offline social behavior or known or predicted personal or personality characteristics;
+17. To intentionally exploit any of the vulnerabilities of a specific group of persons based on their age, social, physical or mental characteristics, in order to materially distort the behavior of a person pertaining to that group in a manner that causes or is likely to cause that person or another person physical or psychological harm;
+18. For military purposes;
+19. To engage in the unauthorized or unlicensed practice of any profession including, but not limited to, financial, legal, medical/health, or other professional practices.
+
+For the license of other third party components, please refer to the following URL:
+https://huggingface.co/Tencent-Hunyuan/HunyuanDiT/blob/main/Notice
+
+--------------------------------------------------------------------
+
+This Model also incorporates insights from Flux's neural network architechtures (https://github.com/black-forest-labs/flux?tab=readme-ov-file). Credits are given to the orginal authors.
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/README-zh.md b/Hunyuan3D-2.1/hy3dshape/README-zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..b526a7e731fcb6fdbef14013d33f411e9af2d422
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/README-zh.md
@@ -0,0 +1,47 @@
+# Hunyuan3D-2.1-Shape
+
+
+# 训练
+
+我们会展示小数据集上DiT的训练全流程
+
+## 数据预处理
+
+渲染和水密化参考[链接](tools/README.md),最终得到如下结构
+
+``` yaml
+dataset/preprocessed/{uid}
+├── geo_data
+│ ├── {uid}_sdf.npz
+│ ├── {uid}_surface.npz
+│ └── {uid}_watertight.obj
+└── render_cond
+ ├── 000.png
+ ├── ...
+ ├── 023.png
+ ├── mesh.ply
+ └── transforms.json
+```
+
+我们提供了一个8个case(均来自Objaverse-XL)预处理后的结果在 tools/mini_trainset,可以直接用于过拟合训练
+
+
+
+## 启动训练
+
+我们提供了可供参考的训练配置文件和启动脚本(默认单机8卡deepspeed训练),用户根据需要自行修改。
+
+配置文件
+```
+configs/dit-from-scratch-overfitting-flowmatching-dinog518-bf16-lr1e4-1024.yaml
+```
+启动脚本
+
+```
+export node_num=1
+export node_rank=0
+export master_ip=0.0.0.0 # set your master_ip
+export config='configs/dit-from-scratch-overfitting-flowmatching-dinog518-bf16-lr1e4-1024.yaml'
+export output_dir='output_folder/dit/overfitting'
+bash scripts/train_deepspeed.sh $node_num $node_rank $master_ip $config $output_dir
+```
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/README.md b/Hunyuan3D-2.1/hy3dshape/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d7b864ed6f80c235423c5f515e153762ec8e0f08
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/README.md
@@ -0,0 +1,54 @@
+# Hunyuan3D-2.1-Shape
+
+## Quick Inference
+
+Given a reference image `image.png`, you can run inference using the following code. The result will be saved as `demo.glb`.
+
+```bash
+python3 minimal_demo.py
+```
+
+**Memory Recommendation:** For we recommend using a GPU with at least **10GB VRAM**.
+
+# Training
+
+Here we demonstrate the complete training workflow of DiT on a small dataset.
+
+## Data Preprocessing
+
+The rendering and watertight mesh generation process is described in detail in [this document](tools/README.md). After preprocessing, the dataset directory structure should look like the following:
+
+```yaml
+dataset/preprocessed/{uid}
+├── geo_data
+│ ├── {uid}_sdf.npz
+│ ├── {uid}_surface.npz
+│ └── {uid}_watertight.obj
+└── render_cond
+ ├── 000.png
+ ├── ...
+ ├── 023.png
+ ├── mesh.ply
+ └── transforms.json
+```
+
+We provide a preprocessed mini_dataset containing 8 cases (all sourced from Objaverse-XL) as `tools/mini_trainset`, which can be used directly for DiT overfitting training experiments.
+
+## Launching Training
+
+We provide example configuration files and launch scripts for reference. By default, the training runs on a single node with 8 GPUs using DeepSpeed. Users can modify the configurations and scripts as needed to suit their environment.
+
+Configuration File
+```
+configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
+```
+Launch Script
+
+```
+export node_num=1
+export node_rank=0
+export master_ip=0.0.0.0 # set your master_ip
+export config=configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
+export output_dir=output_folder/dit/overfitting
+bash scripts/train_deepspeed.sh $node_num $node_rank $master_ip $config $output_dir
+```
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-full-params-finetuning-flowmatching-dinog518-bf16-lr1e5-512.yaml b/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-full-params-finetuning-flowmatching-dinog518-bf16-lr1e5-512.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3128e4447c0bd307be99bb1e11e9405bb8d43524
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-full-params-finetuning-flowmatching-dinog518-bf16-lr1e5-512.yaml
@@ -0,0 +1,174 @@
+name: "DiT: Flux large flowmatching; VAE: 1024 token length; ImageEncoder: DINO Giant; ImageSize: 518"
+
+training:
+ steps: 10_0000_0000
+ use_amp: true
+ amp_type: "bf16"
+ base_lr: 1.e-5
+ gradient_clip_val: 1.0
+ gradient_clip_algorithm: "norm"
+ every_n_train_steps: 2000 # 5000
+ val_check_interval: 50 # 4096
+ limit_val_batches: 16
+
+dataset:
+ target: hy3dshape.data.dit_asl.AlignedShapeLatentModule
+ params:
+ #! Base setting
+ batch_size: 4
+ num_workers: 8
+ val_num_workers: 4
+
+ # Data
+ train_data_list: tools/mini_trainset/preprocessed
+ val_data_list: tools/mini_trainset/preprocessed
+
+ #! Image loading
+ cond_stage_key: "image" # image / text / image_text
+ image_size: 518
+ mean: &mean [0.5, 0.5, 0.5]
+ std: &std [0.5, 0.5, 0.5]
+
+ #! Point cloud sampling
+ pc_size: &pc_size 30720
+ pc_sharpedge_size: &pc_sharpedge_size 30720
+ sharpedge_label: &sharpedge_label true
+ return_normal: true
+
+ #! Augmentation
+ padding: true
+
+model:
+ target: hy3dshape.models.diffusion.flow_matching_sit.Diffuser
+ params:
+ first_stage_key: "surface"
+ cond_stage_key: "image"
+ scale_by_std: false
+ z_scale_factor: &z_scale_factor 0.9990943042622529 # 1 / 1.0009065167661184
+ torch_compile: false
+
+ # ema_config:
+ # ema_model: LitEma
+ # ema_decay: 0.999
+ # ema_inference: false
+
+ first_stage_config:
+ target: hy3dshape.models.autoencoders.ShapeVAE
+ from_pretrained: tencent/Hunyuan3D-2.1
+ params:
+ num_latents: &num_latents 512
+ embed_dim: 64
+ num_freqs: 8
+ include_pi: false
+ heads: 16
+ width: 1024
+ point_feats: 4
+ num_decoder_layers: 16
+ pc_size: *pc_size
+ pc_sharpedge_size: *pc_sharpedge_size
+ qkv_bias: false
+ qk_norm: true
+ scale_factor: *z_scale_factor
+ geo_decoder_mlp_expand_ratio: 4
+ geo_decoder_downsample_ratio: 1
+ geo_decoder_ln_post: true
+
+ cond_stage_config:
+ target: hy3dshape.models.conditioner.SingleImageEncoder
+ params:
+ main_image_encoder:
+ type: DinoImageEncoder # dino giant
+ kwargs:
+ config:
+ attention_probs_dropout_prob: 0.0
+ drop_path_rate: 0.0
+ hidden_act: gelu
+ hidden_dropout_prob: 0.0
+ hidden_size: 1536
+ image_size: 518
+ initializer_range: 0.02
+ layer_norm_eps: 1.e-6
+ layerscale_value: 1.0
+ mlp_ratio: 4
+ model_type: dinov2
+ num_attention_heads: 24
+ num_channels: 3
+ num_hidden_layers: 40
+ patch_size: 14
+ qkv_bias: true
+ torch_dtype: float32
+ use_swiglu_ffn: true
+ image_size: 518
+
+ denoiser_cfg:
+ target: hy3dshape.models.denoisers.hunyuan3ddit.Hunyuan3DDiT
+ params:
+ ckpt_path: ~/.cache/hy3dgen/tencent/Hunyuan3D-2-1-Shape/dit/model.fp16.ckpt
+ input_size: *num_latents
+ context_in_dim: 1536
+ hidden_size: 1024
+ mlp_ratio: 4.0
+ num_heads: 16
+ depth: 16
+ depth_single_blocks: 32
+ axes_dim: [64]
+ theta: 10000
+ qkv_bias: true
+ use_pe: false
+ force_norm_fp32: true
+
+ scheduler_cfg:
+ transport:
+ target: hy3dshape.models.diffusion.transport.create_transport
+ params:
+ path_type: Linear
+ prediction: velocity
+ sampler:
+ target: hy3dshape.models.diffusion.transport.Sampler
+ params: {}
+ ode_params:
+ sampling_method: euler # dopri5 ...
+ num_steps: &num_steps 50
+
+ optimizer_cfg:
+ optimizer:
+ target: torch.optim.AdamW
+ params:
+ betas: [0.9, 0.99]
+ eps: 1.e-6
+ weight_decay: 1.e-2
+
+ scheduler:
+ target: hy3dshape.utils.trainings.lr_scheduler.LambdaWarmUpCosineFactorScheduler
+ params:
+ warm_up_steps: 50 # 5000
+ f_start: 1.e-6
+ f_min: 1.e-3
+ f_max: 1.0
+
+ pipeline_cfg:
+ target: hy3dshape.pipelines.Hunyuan3DDiTFlowMatchingPipeline
+
+ image_processor_cfg:
+ target: hy3dshape.preprocessors.ImageProcessorV2
+ params: {}
+
+callbacks:
+ logger:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalASLDiffuserLogger
+ params:
+ step_frequency: 100 # 10000
+ num_samples: 1
+ sample_times: 1
+ mean: *mean
+ std: *std
+ bounds: [-1.01, -1.01, -1.01, 1.01, 1.01, 1.01]
+ octree_depth: 8
+ num_chunks: 50000
+ mc_level: 0.0
+
+ file_loggers:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalFixASLDiffuserLogger
+ params:
+ step_frequency: 50 # 5000
+ test_data_path: "tools/mini_testset/images.json"
diff --git a/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml b/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..33dcbd0f0c71390b870e40f0e89d0bb7ddaefe70
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/configs/hunyuan3ddit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
@@ -0,0 +1,173 @@
+name: "DiT: Flux large flowmatching; VAE: 1024 token length; ImageEncoder: DINO Giant; ImageSize: 518"
+
+training:
+ steps: 10_0000_0000
+ use_amp: true
+ amp_type: "bf16"
+ base_lr: 1e-4
+ gradient_clip_val: 1.0
+ gradient_clip_algorithm: "norm"
+ every_n_train_steps: 2000 # 5000
+ val_check_interval: 50 # 4096
+ limit_val_batches: 16
+
+dataset:
+ target: hy3dshape.data.dit_asl.AlignedShapeLatentModule
+ params:
+ #! Base setting
+ batch_size: 2
+ num_workers: 8
+ val_num_workers: 4
+
+ # Data
+ train_data_list: tools/mini_trainset/preprocessed
+ val_data_list: tools/mini_trainset/preprocessed
+
+ #! Image loading
+ cond_stage_key: "image" # image / text / image_text
+ image_size: 518
+ mean: &mean [0.5, 0.5, 0.5]
+ std: &std [0.5, 0.5, 0.5]
+
+ #! Point cloud sampling
+ pc_size: &pc_size 10240
+ pc_sharpedge_size: &pc_sharpedge_size 10240
+ sharpedge_label: &sharpedge_label true
+ return_normal: true
+
+ #! Augmentation
+ padding: true
+
+model:
+ target: hy3dshape.models.diffusion.flow_matching_sit.Diffuser
+ params:
+ first_stage_key: "surface"
+ cond_stage_key: "image"
+ scale_by_std: false
+ z_scale_factor: &z_scale_factor 0.9990943042622529 # 1 / 1.0009065167661184
+ torch_compile: false
+
+ # ema_config:
+ # ema_model: LitEma
+ # ema_decay: 0.999
+ # ema_inference: false
+
+ first_stage_config:
+ target: hy3dshape.models.autoencoders.ShapeVAE
+ from_pretrained: tencent/Hunyuan3D-2.1
+ params:
+ num_latents: &num_latents 512
+ embed_dim: 64
+ num_freqs: 8
+ include_pi: false
+ heads: 16
+ width: 1024
+ point_feats: 4
+ num_decoder_layers: 16
+ pc_size: *pc_size
+ pc_sharpedge_size: *pc_sharpedge_size
+ qkv_bias: false
+ qk_norm: true
+ scale_factor: *z_scale_factor
+ geo_decoder_mlp_expand_ratio: 4
+ geo_decoder_downsample_ratio: 1
+ geo_decoder_ln_post: true
+
+ cond_stage_config:
+ target: hy3dshape.models.conditioner.SingleImageEncoder
+ params:
+ main_image_encoder:
+ type: DinoImageEncoder # dino giant
+ kwargs:
+ config:
+ attention_probs_dropout_prob: 0.0
+ drop_path_rate: 0.0
+ hidden_act: gelu
+ hidden_dropout_prob: 0.0
+ hidden_size: 1536
+ image_size: 518
+ initializer_range: 0.02
+ layer_norm_eps: 1.e-6
+ layerscale_value: 1.0
+ mlp_ratio: 4
+ model_type: dinov2
+ num_attention_heads: 24
+ num_channels: 3
+ num_hidden_layers: 40
+ patch_size: 14
+ qkv_bias: true
+ torch_dtype: float32
+ use_swiglu_ffn: true
+ image_size: 518
+
+ denoiser_cfg:
+ target: hy3dshape.models.denoisers.hunyuan3ddit.Hunyuan3DDiT
+ params:
+ input_size: *num_latents
+ context_in_dim: 1536
+ hidden_size: 1024
+ mlp_ratio: 4.0
+ num_heads: 16
+ depth: 8
+ depth_single_blocks: 16
+ axes_dim: [64]
+ theta: 10000
+ qkv_bias: true
+ use_pe: false
+ force_norm_fp32: true
+
+ scheduler_cfg:
+ transport:
+ target: hy3dshape.models.diffusion.transport.create_transport
+ params:
+ path_type: Linear
+ prediction: velocity
+ sampler:
+ target: hy3dshape.models.diffusion.transport.Sampler
+ params: {}
+ ode_params:
+ sampling_method: euler # dopri5 ...
+ num_steps: &num_steps 50
+
+ optimizer_cfg:
+ optimizer:
+ target: torch.optim.AdamW
+ params:
+ betas: [0.9, 0.99]
+ eps: 1.e-6
+ weight_decay: 1.e-2
+
+ scheduler:
+ target: hy3dshape.utils.trainings.lr_scheduler.LambdaWarmUpCosineFactorScheduler
+ params:
+ warm_up_steps: 50 # 5000
+ f_start: 1.e-6
+ f_min: 1.e-3
+ f_max: 1.0
+
+ pipeline_cfg:
+ target: hy3dshape.pipelines.Hunyuan3DDiTFlowMatchingPipeline
+
+ image_processor_cfg:
+ target: hy3dshape.preprocessors.ImageProcessorV2
+ params: {}
+
+callbacks:
+ logger:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalASLDiffuserLogger
+ params:
+ step_frequency: 100 # 10000
+ num_samples: 1
+ sample_times: 1
+ mean: *mean
+ std: *std
+ bounds: [-1.01, -1.01, -1.01, 1.01, 1.01, 1.01]
+ octree_depth: 8
+ num_chunks: 50000
+ mc_level: 0.0
+
+ file_loggers:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalFixASLDiffuserLogger
+ params:
+ step_frequency: 50 # 5000
+ test_data_path: "tools/mini_testset/images.json"
diff --git a/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-finetuning-flowmatching-dinog518-bf16-lr1e5-4096.yaml b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-finetuning-flowmatching-dinog518-bf16-lr1e5-4096.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e9fc84146294cc30d7bb546e8cbc7a36f342c0c5
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-finetuning-flowmatching-dinog518-bf16-lr1e5-4096.yaml
@@ -0,0 +1,180 @@
+name: "DiT: Flux large flowmatching; VAE: 1024 token length; ImageEncoder: DINO Giant; ImageSize: 518"
+
+training:
+ steps: 10_0000_0000
+ use_amp: true
+ amp_type: "bf16"
+ base_lr: 1e-5
+ gradient_clip_val: 1.0
+ gradient_clip_algorithm: "norm"
+ every_n_train_steps: 2000 # 5000
+ val_check_interval: 50 # 4096
+ limit_val_batches: 16
+
+dataset:
+ target: hy3dshape.data.dit_asl.AlignedShapeLatentModule
+ params:
+ #! Base setting
+ batch_size: 4
+ num_workers: 8
+ val_num_workers: 4
+
+ # Data
+ train_data_list: tools/mini_trainset/preprocessed
+ val_data_list: tools/mini_trainset/preprocessed
+
+ #! Image loading
+ cond_stage_key: "image" # image / text / image_text
+ image_size: 518
+ mean: &mean [0.5, 0.5, 0.5]
+ std: &std [0.5, 0.5, 0.5]
+
+ #! Point cloud sampling
+ pc_size: &pc_size 81920
+ pc_sharpedge_size: &pc_sharpedge_size 0
+ sharpedge_label: &sharpedge_label true
+ return_normal: true
+
+ #! Augmentation
+ padding: true
+
+model:
+ target: hy3dshape.models.diffusion.flow_matching_sit.Diffuser
+ params:
+ first_stage_key: "surface"
+ cond_stage_key: "image"
+ scale_by_std: false
+ z_scale_factor: &z_scale_factor 1.0039506158752403
+ torch_compile: false
+
+ # ema_config:
+ # ema_model: LitEma
+ # ema_decay: 0.999
+ # ema_inference: false
+
+ first_stage_config:
+ target: hy3dshape.models.autoencoders.ShapeVAE
+ from_pretrained: tencent/Hunyuan3D-2.1
+ params:
+ num_latents: &num_latents 4096
+ embed_dim: 64
+ num_freqs: 8
+ include_pi: false
+ heads: 16
+ width: 1024
+ num_encoder_layers: 8
+ num_decoder_layers: 16
+ qkv_bias: false
+ qk_norm: true
+ scale_factor: *z_scale_factor
+ geo_decoder_mlp_expand_ratio: 4
+ geo_decoder_downsample_ratio: 1
+ geo_decoder_ln_post: true
+ point_feats: 4
+ pc_size: *pc_size
+ pc_sharpedge_size: *pc_sharpedge_size
+
+ cond_stage_config:
+ target: hy3dshape.models.conditioner.SingleImageEncoder
+ params:
+ main_image_encoder:
+ type: DinoImageEncoder # dino large
+ kwargs:
+ config:
+ attention_probs_dropout_prob: 0.0
+ drop_path_rate: 0.0
+ hidden_act: gelu
+ hidden_dropout_prob: 0.0
+ hidden_size: 1024
+ image_size: 518
+ initializer_range: 0.02
+ layer_norm_eps: 1.e-6
+ layerscale_value: 1.0
+ mlp_ratio: 4
+ model_type: dinov2
+ num_attention_heads: 16
+ num_channels: 3
+ num_hidden_layers: 24
+ patch_size: 14
+ qkv_bias: true
+ torch_dtype: float32
+ use_swiglu_ffn: false
+ image_size: 518
+ use_cls_token: true
+
+
+ denoiser_cfg:
+ target: hy3dshape.models.denoisers.hunyuandit.HunYuanDiTPlain
+ params:
+ input_size: *num_latents
+ in_channels: 64
+ hidden_size: 2048
+ context_dim: 1024
+ depth: 21
+ num_heads: 16
+ qk_norm: true
+ text_len: 1370
+ with_decoupled_ca: false
+ use_attention_pooling: false
+ qk_norm_type: 'rms'
+ qkv_bias: false
+ use_pos_emb: false
+ num_moe_layers: 6
+ num_experts: 8
+ moe_top_k: 2
+
+ scheduler_cfg:
+ transport:
+ target: hy3dshape.models.diffusion.transport.create_transport
+ params:
+ path_type: Linear
+ prediction: velocity
+ sampler:
+ target: hy3dshape.models.diffusion.transport.Sampler
+ params: {}
+ ode_params:
+ sampling_method: euler # dopri5 ...
+ num_steps: &num_steps 50
+
+ optimizer_cfg:
+ optimizer:
+ target: torch.optim.AdamW
+ params:
+ betas: [0.9, 0.99]
+ eps: 1.e-6
+ weight_decay: 1.e-2
+
+ scheduler:
+ target: hy3dshape.utils.trainings.lr_scheduler.LambdaWarmUpCosineFactorScheduler
+ params:
+ warm_up_steps: 50 # 5000
+ f_start: 1.e-6
+ f_min: 1.e-3
+ f_max: 1.0
+
+ pipeline_cfg:
+ target: hy3dshape.pipelines.Hunyuan3DDiTFlowMatchingPipeline
+
+ image_processor_cfg:
+ target: hy3dshape.preprocessors.ImageProcessorV2
+ params: {}
+
+callbacks:
+ logger:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalASLDiffuserLogger
+ params:
+ step_frequency: 100 # 10000
+ num_samples: 1
+ sample_times: 1
+ mean: *mean
+ std: *std
+ bounds: [-1.01, -1.01, -1.01, 1.01, 1.01, 1.01]
+ octree_depth: 8
+ num_chunks: 50000
+ mc_level: 0.0
+
+ file_loggers:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalFixASLDiffuserLogger
+ params:
+ step_frequency: 50 # 5000
+ test_data_path: "tools/mini_testset/images.json"
diff --git a/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-4096.yaml b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-4096.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..82e7ebb4b7475c6ea19c52bf63715b0fe40ecd20
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-4096.yaml
@@ -0,0 +1,180 @@
+name: "DiT: Flux large flowmatching; VAE: 1024 token length; ImageEncoder: DINO Giant; ImageSize: 518"
+
+training:
+ steps: 10_0000_0000
+ use_amp: true
+ amp_type: "bf16"
+ base_lr: 1e-4
+ gradient_clip_val: 1.0
+ gradient_clip_algorithm: "norm"
+ every_n_train_steps: 2000 # 5000
+ val_check_interval: 50 # 4096
+ limit_val_batches: 16
+
+dataset:
+ target: hy3dshape.data.dit_asl.AlignedShapeLatentModule
+ params:
+ #! Base setting
+ batch_size: 2
+ num_workers: 8
+ val_num_workers: 4
+
+ # Data
+ train_data_list: tools/mini_trainset/preprocessed
+ val_data_list: tools/mini_trainset/preprocessed
+
+ #! Image loading
+ cond_stage_key: "image" # image / text / image_text
+ image_size: 518
+ mean: &mean [0.5, 0.5, 0.5]
+ std: &std [0.5, 0.5, 0.5]
+
+ #! Point cloud sampling
+ pc_size: &pc_size 81920
+ pc_sharpedge_size: &pc_sharpedge_size 0
+ sharpedge_label: &sharpedge_label true
+ return_normal: true
+
+ #! Augmentation
+ padding: true
+
+model:
+ target: hy3dshape.models.diffusion.flow_matching_sit.Diffuser
+ params:
+ first_stage_key: "surface"
+ cond_stage_key: "image"
+ scale_by_std: false
+ z_scale_factor: &z_scale_factor 1.0039506158752403
+ torch_compile: false
+
+ # ema_config:
+ # ema_model: LitEma
+ # ema_decay: 0.999
+ # ema_inference: false
+
+ first_stage_config:
+ target: hy3dshape.models.autoencoders.ShapeVAE
+ from_pretrained: tencent/Hunyuan3D-2.1
+ params:
+ num_latents: &num_latents 4096
+ embed_dim: 64
+ num_freqs: 8
+ include_pi: false
+ heads: 16
+ width: 1024
+ num_encoder_layers: 8
+ num_decoder_layers: 16
+ qkv_bias: false
+ qk_norm: true
+ scale_factor: *z_scale_factor
+ geo_decoder_mlp_expand_ratio: 4
+ geo_decoder_downsample_ratio: 1
+ geo_decoder_ln_post: true
+ point_feats: 4
+ pc_size: *pc_size
+ pc_sharpedge_size: *pc_sharpedge_size
+
+ cond_stage_config:
+ target: hy3dshape.models.conditioner.SingleImageEncoder
+ params:
+ main_image_encoder:
+ type: DinoImageEncoder # dino large
+ kwargs:
+ config:
+ attention_probs_dropout_prob: 0.0
+ drop_path_rate: 0.0
+ hidden_act: gelu
+ hidden_dropout_prob: 0.0
+ hidden_size: 1024
+ image_size: 518
+ initializer_range: 0.02
+ layer_norm_eps: 1.e-6
+ layerscale_value: 1.0
+ mlp_ratio: 4
+ model_type: dinov2
+ num_attention_heads: 16
+ num_channels: 3
+ num_hidden_layers: 24
+ patch_size: 14
+ qkv_bias: true
+ torch_dtype: float32
+ use_swiglu_ffn: false
+ image_size: 518
+ use_cls_token: true
+
+
+ denoiser_cfg:
+ target: hy3dshape.models.denoisers.hunyuandit.HunYuanDiTPlain
+ params:
+ input_size: *num_latents
+ in_channels: 64
+ hidden_size: 2048
+ context_dim: 1024
+ depth: 11
+ num_heads: 16
+ qk_norm: true
+ text_len: 1370
+ with_decoupled_ca: false
+ use_attention_pooling: false
+ qk_norm_type: 'rms'
+ qkv_bias: false
+ use_pos_emb: false
+ num_moe_layers: 6
+ num_experts: 8
+ moe_top_k: 2
+
+ scheduler_cfg:
+ transport:
+ target: hy3dshape.models.diffusion.transport.create_transport
+ params:
+ path_type: Linear
+ prediction: velocity
+ sampler:
+ target: hy3dshape.models.diffusion.transport.Sampler
+ params: {}
+ ode_params:
+ sampling_method: euler # dopri5 ...
+ num_steps: &num_steps 50
+
+ optimizer_cfg:
+ optimizer:
+ target: torch.optim.AdamW
+ params:
+ betas: [0.9, 0.99]
+ eps: 1.e-6
+ weight_decay: 1.e-2
+
+ scheduler:
+ target: hy3dshape.utils.trainings.lr_scheduler.LambdaWarmUpCosineFactorScheduler
+ params:
+ warm_up_steps: 50 # 5000
+ f_start: 1.e-6
+ f_min: 1.e-3
+ f_max: 1.0
+
+ pipeline_cfg:
+ target: hy3dshape.pipelines.Hunyuan3DDiTFlowMatchingPipeline
+
+ image_processor_cfg:
+ target: hy3dshape.preprocessors.ImageProcessorV2
+ params: {}
+
+callbacks:
+ logger:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalASLDiffuserLogger
+ params:
+ step_frequency: 100 # 10000
+ num_samples: 1
+ sample_times: 1
+ mean: *mean
+ std: *std
+ bounds: [-1.01, -1.01, -1.01, 1.01, 1.01, 1.01]
+ octree_depth: 8
+ num_chunks: 50000
+ mc_level: 0.0
+
+ file_loggers:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalFixASLDiffuserLogger
+ params:
+ step_frequency: 50 # 5000
+ test_data_path: "tools/mini_testset/images.json"
diff --git a/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ffed3aa9a9b721c23059e8f16f94d08e5b16cab4
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/configs/hunyuandit-mini-overfitting-flowmatching-dinog518-bf16-lr1e4-512.yaml
@@ -0,0 +1,180 @@
+name: "DiT: Flux large flowmatching; VAE: 1024 token length; ImageEncoder: DINO Giant; ImageSize: 518"
+
+training:
+ steps: 10_0000_0000
+ use_amp: true
+ amp_type: "bf16"
+ base_lr: 1e-4
+ gradient_clip_val: 1.0
+ gradient_clip_algorithm: "norm"
+ every_n_train_steps: 2000 # 5000
+ val_check_interval: 50 # 4096
+ limit_val_batches: 16
+
+dataset:
+ target: hy3dshape.data.dit_asl.AlignedShapeLatentModule
+ params:
+ #! Base setting
+ batch_size: 2
+ num_workers: 8
+ val_num_workers: 4
+
+ # Data
+ train_data_list: tools/mini_trainset/preprocessed
+ val_data_list: tools/mini_trainset/preprocessed
+
+ #! Image loading
+ cond_stage_key: "image" # image / text / image_text
+ image_size: 518
+ mean: &mean [0.5, 0.5, 0.5]
+ std: &std [0.5, 0.5, 0.5]
+
+ #! Point cloud sampling
+ pc_size: &pc_size 81920
+ pc_sharpedge_size: &pc_sharpedge_size 0
+ sharpedge_label: &sharpedge_label true
+ return_normal: true
+
+ #! Augmentation
+ padding: true
+
+model:
+ target: hy3dshape.models.diffusion.flow_matching_sit.Diffuser
+ params:
+ first_stage_key: "surface"
+ cond_stage_key: "image"
+ scale_by_std: false
+ z_scale_factor: &z_scale_factor 1.0039506158752403
+ torch_compile: false
+
+ # ema_config:
+ # ema_model: LitEma
+ # ema_decay: 0.999
+ # ema_inference: false
+
+ first_stage_config:
+ target: hy3dshape.models.autoencoders.ShapeVAE
+ from_pretrained: tencent/Hunyuan3D-2.1
+ params:
+ num_latents: &num_latents 512
+ embed_dim: 64
+ num_freqs: 8
+ include_pi: false
+ heads: 16
+ width: 1024
+ num_encoder_layers: 8
+ num_decoder_layers: 16
+ qkv_bias: false
+ qk_norm: true
+ scale_factor: *z_scale_factor
+ geo_decoder_mlp_expand_ratio: 4
+ geo_decoder_downsample_ratio: 1
+ geo_decoder_ln_post: true
+ point_feats: 4
+ pc_size: *pc_size
+ pc_sharpedge_size: *pc_sharpedge_size
+
+ cond_stage_config:
+ target: hy3dshape.models.conditioner.SingleImageEncoder
+ params:
+ main_image_encoder:
+ type: DinoImageEncoder # dino large
+ kwargs:
+ config:
+ attention_probs_dropout_prob: 0.0
+ drop_path_rate: 0.0
+ hidden_act: gelu
+ hidden_dropout_prob: 0.0
+ hidden_size: 1024
+ image_size: 518
+ initializer_range: 0.02
+ layer_norm_eps: 1.e-6
+ layerscale_value: 1.0
+ mlp_ratio: 4
+ model_type: dinov2
+ num_attention_heads: 16
+ num_channels: 3
+ num_hidden_layers: 24
+ patch_size: 14
+ qkv_bias: true
+ torch_dtype: float32
+ use_swiglu_ffn: false
+ image_size: 518
+ use_cls_token: true
+
+
+ denoiser_cfg:
+ target: hy3dshape.models.denoisers.hunyuandit.HunYuanDiTPlain
+ params:
+ input_size: *num_latents
+ in_channels: 64
+ hidden_size: 768
+ context_dim: 1024
+ depth: 6
+ num_heads: 12
+ qk_norm: true
+ text_len: 1370
+ with_decoupled_ca: false
+ use_attention_pooling: false
+ qk_norm_type: 'rms'
+ qkv_bias: false
+ use_pos_emb: false
+ num_moe_layers: 3
+ num_experts: 4
+ moe_top_k: 2
+
+ scheduler_cfg:
+ transport:
+ target: hy3dshape.models.diffusion.transport.create_transport
+ params:
+ path_type: Linear
+ prediction: velocity
+ sampler:
+ target: hy3dshape.models.diffusion.transport.Sampler
+ params: {}
+ ode_params:
+ sampling_method: euler # dopri5 ...
+ num_steps: &num_steps 50
+
+ optimizer_cfg:
+ optimizer:
+ target: torch.optim.AdamW
+ params:
+ betas: [0.9, 0.99]
+ eps: 1.e-6
+ weight_decay: 1.e-2
+
+ scheduler:
+ target: hy3dshape.utils.trainings.lr_scheduler.LambdaWarmUpCosineFactorScheduler
+ params:
+ warm_up_steps: 50 # 5000
+ f_start: 1.e-6
+ f_min: 1.e-3
+ f_max: 1.0
+
+ pipeline_cfg:
+ target: hy3dshape.pipelines.Hunyuan3DDiTFlowMatchingPipeline
+
+ image_processor_cfg:
+ target: hy3dshape.preprocessors.ImageProcessorV2
+ params: {}
+
+callbacks:
+ logger:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalASLDiffuserLogger
+ params:
+ step_frequency: 100 # 10000
+ num_samples: 1
+ sample_times: 1
+ mean: *mean
+ std: *std
+ bounds: [-1.01, -1.01, -1.01, 1.01, 1.01, 1.01]
+ octree_depth: 8
+ num_chunks: 50000
+ mc_level: 0.0
+
+ file_loggers:
+ target: hy3dshape.utils.trainings.mesh_log_callback.ImageConditionalFixASLDiffuserLogger
+ params:
+ step_frequency: 50 # 5000
+ test_data_path: "tools/mini_testset/images.json"
diff --git a/Hunyuan3D-2.1/hy3dshape/demos/demo.png b/Hunyuan3D-2.1/hy3dshape/demos/demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c069409fe6c9b91e68ddaf13a049bab61a1523d
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/demos/demo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4260b9a45c39fc4045bae81d27f8eb17127cdb201df614193077268d996ce436
+size 151014
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/__init__.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b1f9cce42c1d2bef94bbb2d7b088d24e76fe01e
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/__init__.py
@@ -0,0 +1,17 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from .pipelines import Hunyuan3DDiTPipeline, Hunyuan3DDiTFlowMatchingPipeline
+from .postprocessors import FaceReducer, FloaterRemover, DegenerateFaceRemover, MeshSimplifier
+from .preprocessors import ImageProcessorV2, IMAGE_PROCESSORS, DEFAULT_IMAGEPROCESSOR
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/dit_asl.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/dit_asl.py
new file mode 100644
index 0000000000000000000000000000000000000000..21b045d06ebca12b544c974939a7ab4a56a6d349
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/dit_asl.py
@@ -0,0 +1,384 @@
+# -*- coding: utf-8 -*-
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+
+import os
+import io
+import sys
+import time
+import random
+import traceback
+from typing import Optional, Union, List, Tuple, Dict
+
+import json
+import glob
+import cv2
+import numpy as np
+import trimesh
+
+import torch
+import torchvision.transforms as transforms
+from pytorch_lightning import LightningDataModule
+from pytorch_lightning.utilities import rank_zero_info
+
+from .utils import worker_init_fn, pytorch_worker_seed, make_seed
+
+
+class ResampledShards(torch.utils.data.dataset.IterableDataset):
+ def __init__(self, datalist, nshards=sys.maxsize, worker_seed=None, deterministic=False):
+ super().__init__()
+ self.datalist = datalist
+ self.nshards = nshards
+ # If no worker_seed provided, use pytorch_worker_seed function; else use given seed
+ self.worker_seed = pytorch_worker_seed if worker_seed is None else worker_seed
+ self.deterministic = deterministic
+ self.epoch = -1
+
+ def __iter__(self):
+ self.epoch += 1
+ if self.deterministic:
+ seed = make_seed(self.worker_seed(), self.epoch)
+ else:
+ seed = make_seed(self.worker_seed(), self.epoch,
+ os.getpid(), time.time_ns(), os.urandom(4))
+ self.rng = random.Random(seed)
+ for _ in range(self.nshards):
+ index = self.rng.randint(0, len(self.datalist) - 1)
+ yield self.datalist[index]
+
+
+def read_npz(data):
+ # Load a numpy .npz file from a file path or file-like object
+ # The commented line shows how to load from bytes in memory
+ # return np.load(io.BytesIO(data))
+ return np.load(data)
+
+
+def read_json(path):
+ # Read and parse a JSON file from the given file path
+ with open(path, 'r', encoding='utf-8') as file:
+ data = json.load(file)
+ return data
+
+
+def padding(image, mask, center=True, padding_ratio_range=[1.15, 1.15]):
+ """
+ Pad the input image and mask to a square shape with padding ratio.
+
+ Args:
+ image (np.ndarray): Input image array of shape (H, W, C).
+ mask (np.ndarray): Corresponding mask array of shape (H, W).
+ center (bool): Whether to center the original image in the padded output.
+ padding_ratio_range (list): Range [min, max] to randomly select padding ratio.
+
+ Returns:
+ newimg (np.ndarray): Padded image of shape (resize_side, resize_side, 3).
+ newmask (np.ndarray): Padded mask of shape (resize_side, resize_side).
+ """
+ h, w = image.shape[:2]
+ max_side = max(h, w)
+
+ # Select padding ratio either fixed or randomly within the given range
+ if padding_ratio_range[0] == padding_ratio_range[1]:
+ padding_ratio = padding_ratio_range[0]
+ else:
+ padding_ratio = random.uniform(padding_ratio_range[0], padding_ratio_range[1])
+ resize_side = int(max_side * padding_ratio)
+ # resize_side = int(max_side * 1.15)
+
+ pad_h = resize_side - h
+ pad_w = resize_side - w
+ if center:
+ start_h = pad_h // 2
+ else:
+ start_h = pad_h - resize_side // 20
+
+ start_w = pad_w // 2
+
+ # Create new white image and black mask with padded size
+ newimg = np.ones((resize_side, resize_side, 3), dtype=np.uint8) * 255
+ newmask = np.zeros((resize_side, resize_side), dtype=np.uint8)
+
+ # Place original image and mask into the padded canvas
+ newimg[start_h:start_h + h, start_w:start_w + w] = image
+ newmask[start_h:start_h + h, start_w:start_w + w] = mask
+
+ return newimg, newmask
+
+
+def viz_pc(surface, normal, image_input, name):
+ image_input = image_input.cpu().numpy()
+ image_input = image_input.transpose(1, 2, 0) * 0.5 + 0.5
+ image_input = (image_input * 255).astype(np.uint8)
+ cv2.imwrite(name + '.png', cv2.cvtColor(image_input, cv2.COLOR_RGB2BGR))
+ surface = surface.cpu().numpy()
+ normal = normal.cpu().numpy()
+ surface_mesh = trimesh.Trimesh(surface, vertex_colors=(normal + 1) / 2)
+ surface_mesh.export(name + '.obj')
+
+
+class AlignedShapeLatentDataset(torch.utils.data.dataset.IterableDataset):
+ def __init__(
+ self,
+ data_list: str = None,
+ cond_stage_key: str = "image",
+ image_transform = None,
+ pc_size: int = 2048,
+ pc_sharpedge_size: int = 2048,
+ sharpedge_label: bool = False,
+ return_normal: bool = False,
+ deterministic = False,
+ worker_seed = None,
+ padding = True,
+ padding_ratio_range=[1.15, 1.15]
+ ):
+ super().__init__()
+ if isinstance(data_list, str) and data_list.endswith('.json'):
+ self.data_list = read_json(data_list_json)
+ elif isinstance(data_list, str) and os.path.isdir(data_list):
+ self.data_list = glob.glob(data_list + '/*')
+ else:
+ self.data_list = data_list
+ assert isinstance(self.data_list, list)
+ self.rng = random.Random(0)
+
+ self.cond_stage_key = cond_stage_key
+ self.image_transform = image_transform
+
+ self.pc_size = pc_size
+ self.pc_sharpedge_size = pc_sharpedge_size
+ self.sharpedge_label = sharpedge_label
+ self.return_normal = return_normal
+
+ self.padding = padding
+ self.padding_ratio_range = padding_ratio_range
+
+ rank_zero_info(f'*' * 50)
+ rank_zero_info(f'Dataset Infos:')
+ rank_zero_info(f'# of 3D file: {len(self.data_list)}')
+ rank_zero_info(f'# of Surface Points: {self.pc_size}')
+ rank_zero_info(f'# of Sharpedge Surface Points: {self.pc_sharpedge_size}')
+ rank_zero_info(f'Using sharp edge label: {self.sharpedge_label}')
+ rank_zero_info(f'*' * 50)
+
+
+ def load_surface_sdf_points(self, rng, random_surface, sharpedge_surface):
+ surface_normal = []
+ if self.pc_size > 0:
+ ind = rng.choice(random_surface.shape[0], self.pc_size, replace=False)
+ random_surface = random_surface[ind]
+ if self.sharpedge_label:
+ sharpedge_label = np.zeros((self.pc_size, 1))
+ random_surface = np.concatenate((random_surface, sharpedge_label), axis=1)
+ surface_normal.append(random_surface)
+
+ if self.pc_sharpedge_size > 0:
+ ind_sharpedge = rng.choice(sharpedge_surface.shape[0], self.pc_sharpedge_size, replace=False)
+ sharpedge_surface = sharpedge_surface[ind_sharpedge]
+ if self.sharpedge_label:
+ sharpedge_label = np.ones((self.pc_sharpedge_size, 1))
+ sharpedge_surface = np.concatenate((sharpedge_surface, sharpedge_label), axis=1)
+ surface_normal.append(sharpedge_surface)
+
+ surface_normal = np.concatenate(surface_normal, axis=0)
+ surface_normal = torch.FloatTensor(surface_normal)
+ surface = surface_normal[:, 0:3]
+ normal = surface_normal[:, 3:6]
+ assert surface.shape[0] == self.pc_size + self.pc_sharpedge_size
+
+ geo_points = 0.0
+ normal = torch.nn.functional.normalize(normal, p=2, dim=1)
+ if self.return_normal:
+ surface = torch.cat([surface, normal], dim=-1)
+ if self.sharpedge_label:
+ surface = torch.cat([surface, surface_normal[:, -1:]], dim=-1)
+ return surface, geo_points
+
+ def load_render(self, imgs_path):
+ imgs_choice = self.rng.sample(imgs_path, 1)
+ images, masks = [], []
+ for image_path in imgs_choice:
+ image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
+ assert image.shape[2] == 4
+ alpha = image[:, :, 3:4].astype(np.float32) / 255
+ forground = image[:, :, :3]
+ background = np.ones_like(forground) * 255
+ img_new = forground * alpha + background * (1 - alpha)
+ image = img_new.astype(np.uint8)
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
+ mask = (alpha[:, :, 0] * 255).astype(np.uint8)
+
+ if self.padding:
+ h, w = image.shape[:2]
+ binary = mask > 0.3
+ non_zero_coords = np.argwhere(binary)
+ x_min, y_min = non_zero_coords.min(axis=0)
+ x_max, y_max = non_zero_coords.max(axis=0)
+ image, mask = padding(
+ image[max(x_min - 5, 0):min(x_max + 5, h), max(y_min - 5, 0):min(y_max + 5, w)],
+ mask[max(x_min - 5, 0):min(x_max + 5, h), max(y_min - 5, 0):min(y_max + 5, w)],
+ center=True, padding_ratio_range=self.padding_ratio_range)
+
+ if self.image_transform:
+ image = self.image_transform(image)
+ mask = np.stack((mask, mask, mask), axis=-1)
+ mask = self.image_transform(mask)
+
+ images.append(image)
+ masks.append(mask)
+
+ images = torch.cat(images, dim=0)
+ masks = torch.cat(masks, dim=0)[:1, ...]
+ return images, masks
+
+ def decode(self, item):
+ uid = item.split('/')[-1]
+ render_img_paths = [os.path.join(item, f'render_cond/{i:03d}.png') for i in range(24)]
+ # transforms_json_path = os.path.join(item, 'render_cond/transforms.json')
+ surface_npz_path = os.path.join(item, f'geo_data/{uid}_surface.npz')
+ # sdf_npz_path = os.path.join(item, f'geo_data/{uid}_sdf.npz')
+ # watertight_obj_path = os.path.join(item, f'geo_data/{uid}_watertight.obj')
+ sample = {}
+ sample["image"] = render_img_paths
+ surface_data = read_npz(surface_npz_path)
+ sample["random_surface"] = surface_data['random_surface']
+ sample["sharpedge_surface"] = surface_data['sharp_surface']
+ return sample
+
+ def transform(self, sample):
+ rng = np.random.default_rng()
+ random_surface = sample.get("random_surface", 0)
+ sharpedge_surface = sample.get("sharpedge_surface", 0)
+ image_input, mask_input = self.load_render(sample['image'])
+ surface, geo_points = self.load_surface_sdf_points(rng, random_surface, sharpedge_surface)
+ sample = {
+ "surface": surface,
+ "geo_points": geo_points,
+ "image": image_input,
+ "mask": mask_input,
+ }
+ return sample
+
+ def __iter__(self):
+ total_num = 0
+ failed_num = 0
+ for data in ResampledShards(self.data_list):
+ total_num += 1
+ if total_num % 1000 == 0:
+ print(f"Current failure rate of data loading:")
+ print(f"{failed_num}/{total_num}={failed_num/total_num}")
+ try:
+ sample = self.decode(data)
+ sample = self.transform(sample)
+ except Exception as err:
+ print(err)
+ failed_num += 1
+ continue
+ yield sample
+
+
+class AlignedShapeLatentModule(LightningDataModule):
+ def __init__(
+ self,
+ batch_size: int = 1,
+ num_workers: int = 4,
+ val_num_workers: int = 2,
+ train_data_list: str = None,
+ val_data_list: str = None,
+ cond_stage_key: str = "all",
+ image_size: int = 224,
+ mean: Union[List[float], Tuple[float]] = (0.485, 0.456, 0.406),
+ std: Union[List[float], Tuple[float]] = (0.229, 0.224, 0.225),
+ pc_size: int = 2048,
+ pc_sharpedge_size: int = 2048,
+ sharpedge_label: bool = False,
+ return_normal: bool = False,
+ padding = True,
+ padding_ratio_range=[1.15, 1.15]
+ ):
+
+ super().__init__()
+ self.batch_size = batch_size
+ self.num_workers = num_workers
+ self.val_num_workers = val_num_workers
+
+ self.train_data_list = train_data_list
+ self.val_data_list = val_data_list
+
+ self.cond_stage_key = cond_stage_key
+ self.image_size = image_size
+ self.mean = mean
+ self.std = std
+ self.train_image_transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Resize(self.image_size),
+ transforms.Normalize(mean=self.mean, std=self.std)])
+ self.val_image_transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Resize(self.image_size),
+ transforms.Normalize(mean=self.mean, std=self.std)])
+
+ self.pc_size = pc_size
+ self.pc_sharpedge_size = pc_sharpedge_size
+ self.sharpedge_label = sharpedge_label
+ self.return_normal = return_normal
+
+ self.padding = padding
+ self.padding_ratio_range = padding_ratio_range
+
+ def train_dataloader(self):
+ asl_params = {
+ "data_list": self.train_data_list,
+ "cond_stage_key": self.cond_stage_key,
+ "image_transform": self.train_image_transform,
+ "pc_size": self.pc_size,
+ "pc_sharpedge_size": self.pc_sharpedge_size,
+ "sharpedge_label": self.sharpedge_label,
+ "return_normal": self.return_normal,
+ "padding": self.padding,
+ "padding_ratio_range": self.padding_ratio_range
+ }
+ dataset = AlignedShapeLatentDataset(**asl_params)
+ return torch.utils.data.DataLoader(
+ dataset,
+ batch_size=self.batch_size,
+ num_workers=self.num_workers,
+ pin_memory=True,
+ drop_last=True,
+ worker_init_fn=worker_init_fn,
+ )
+
+ def val_dataloader(self):
+ asl_params = {
+ "data_list": self.val_data_list,
+ "cond_stage_key": self.cond_stage_key,
+ "image_transform": self.val_image_transform,
+ "pc_size": self.pc_size,
+ "pc_sharpedge_size": self.pc_sharpedge_size,
+ "sharpedge_label": self.sharpedge_label,
+ "return_normal": self.return_normal,
+ "padding": self.padding,
+ "padding_ratio_range": self.padding_ratio_range
+ }
+ dataset = AlignedShapeLatentDataset(**asl_params)
+ return torch.utils.data.DataLoader(
+ dataset,
+ batch_size=self.batch_size,
+ num_workers=self.val_num_workers,
+ pin_memory=True,
+ drop_last=True,
+ worker_init_fn=worker_init_fn,
+ )
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/utils.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..52adca1106abf1ce6375970eac7ac1fbe2824ff0
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/data/utils.py
@@ -0,0 +1,186 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2017-2021 NVIDIA CORPORATION. All rights reserved.
+# This file is part of the WebDataset library.
+# See the LICENSE file for licensing terms (BSD-style).
+
+
+"""Miscellaneous utility functions."""
+
+import importlib
+import itertools as itt
+import os
+import re
+import sys
+from typing import Any, Callable, Iterator, Union
+import torch
+import numpy as np
+
+
+def make_seed(*args):
+ seed = 0
+ for arg in args:
+ seed = (seed * 31 + hash(arg)) & 0x7FFFFFFF
+ return seed
+
+
+class PipelineStage:
+ def invoke(self, *args, **kw):
+ raise NotImplementedError
+
+
+def identity(x: Any) -> Any:
+ """Return the argument as is."""
+ return x
+
+
+def safe_eval(s: str, expr: str = "{}"):
+ """Evaluate the given expression more safely."""
+ if re.sub("[^A-Za-z0-9_]", "", s) != s:
+ raise ValueError(f"safe_eval: illegal characters in: '{s}'")
+ return eval(expr.format(s))
+
+
+def lookup_sym(sym: str, modules: list):
+ """Look up a symbol in a list of modules."""
+ for mname in modules:
+ module = importlib.import_module(mname, package="webdataset")
+ result = getattr(module, sym, None)
+ if result is not None:
+ return result
+ return None
+
+
+def repeatedly0(
+ loader: Iterator, nepochs: int = sys.maxsize, nbatches: int = sys.maxsize
+):
+ """Repeatedly returns batches from a DataLoader."""
+ for _ in range(nepochs):
+ yield from itt.islice(loader, nbatches)
+
+
+def guess_batchsize(batch: Union[tuple, list]):
+ """Guess the batch size by looking at the length of the first element in a tuple."""
+ return len(batch[0])
+
+
+def repeatedly(
+ source: Iterator,
+ nepochs: int = None,
+ nbatches: int = None,
+ nsamples: int = None,
+ batchsize: Callable[..., int] = guess_batchsize,
+):
+ """Repeatedly yield samples from an iterator."""
+ epoch = 0
+ batch = 0
+ total = 0
+ while True:
+ for sample in source:
+ yield sample
+ batch += 1
+ if nbatches is not None and batch >= nbatches:
+ return
+ if nsamples is not None:
+ total += guess_batchsize(sample)
+ if total >= nsamples:
+ return
+ epoch += 1
+ if nepochs is not None and epoch >= nepochs:
+ return
+
+
+def pytorch_worker_info(group=None): # sourcery skip: use-contextlib-suppress
+ """Return node and worker info for PyTorch and some distributed environments."""
+ rank = 0
+ world_size = 1
+ worker = 0
+ num_workers = 1
+ if "RANK" in os.environ and "WORLD_SIZE" in os.environ:
+ rank = int(os.environ["RANK"])
+ world_size = int(os.environ["WORLD_SIZE"])
+ else:
+ try:
+ import torch.distributed
+
+ if torch.distributed.is_available() and torch.distributed.is_initialized():
+ group = group or torch.distributed.group.WORLD
+ rank = torch.distributed.get_rank(group=group)
+ world_size = torch.distributed.get_world_size(group=group)
+ except ModuleNotFoundError:
+ pass
+ if "WORKER" in os.environ and "NUM_WORKERS" in os.environ:
+ worker = int(os.environ["WORKER"])
+ num_workers = int(os.environ["NUM_WORKERS"])
+ else:
+ try:
+ import torch.utils.data
+
+ worker_info = torch.utils.data.get_worker_info()
+ if worker_info is not None:
+ worker = worker_info.id
+ num_workers = worker_info.num_workers
+ except ModuleNotFoundError:
+ pass
+
+ return rank, world_size, worker, num_workers
+
+
+def pytorch_worker_seed(group=None):
+ """Compute a distinct, deterministic RNG seed for each worker and node."""
+ rank, world_size, worker, num_workers = pytorch_worker_info(group=group)
+ return rank * 1000 + worker
+
+def worker_init_fn(_):
+ worker_info = torch.utils.data.get_worker_info()
+ worker_id = worker_info.id
+
+ # dataset = worker_info.dataset
+ # split_size = dataset.num_records // worker_info.num_workers
+ # # reset num_records to the true number to retain reliable length information
+ # dataset.sample_ids = dataset.valid_ids[worker_id * split_size:(worker_id + 1) * split_size]
+ # current_id = np.random.choice(len(np.random.get_state()[1]), 1)
+ # return np.random.seed(np.random.get_state()[1][current_id] + worker_id)
+
+ return np.random.seed(np.random.get_state()[1][0] + worker_id)
+
+
+def collation_fn(samples, combine_tensors=True, combine_scalars=True):
+ """
+
+ Args:
+ samples (list[dict]):
+ combine_tensors:
+ combine_scalars:
+
+ Returns:
+
+ """
+
+ result = {}
+
+ keys = samples[0].keys()
+
+ for key in keys:
+ result[key] = []
+
+ for sample in samples:
+ for key in keys:
+ val = sample[key]
+ result[key].append(val)
+
+ for key in keys:
+ val_list = result[key]
+ if isinstance(val_list[0], (int, float)):
+ if combine_scalars:
+ result[key] = np.array(result[key])
+
+ elif isinstance(val_list[0], torch.Tensor):
+ if combine_tensors:
+ result[key] = torch.stack(val_list)
+
+ elif isinstance(val_list[0], np.ndarray):
+ if combine_tensors:
+ result[key] = np.stack(val_list)
+
+ return result
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/pipelines.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/pipelines.py
new file mode 100644
index 0000000000000000000000000000000000000000..e02239b49e5870254d56da4abee6213c1f777eb4
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/pipelines.py
@@ -0,0 +1,788 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import copy
+import importlib
+import inspect
+import os
+from typing import List, Optional, Union
+
+import numpy as np
+import torch
+import trimesh
+import yaml
+from PIL import Image
+from diffusers.utils.torch_utils import randn_tensor
+from diffusers.utils.import_utils import is_accelerate_version, is_accelerate_available
+from tqdm import tqdm
+
+import copy
+from .models.autoencoders import ShapeVAE
+from .models.autoencoders import SurfaceExtractors
+from .utils import logger, synchronize_timer, smart_load_model
+
+
+def retrieve_timesteps(
+ scheduler,
+ num_inference_steps: Optional[int] = None,
+ device: Optional[Union[str, torch.device]] = None,
+ timesteps: Optional[List[int]] = None,
+ sigmas: Optional[List[float]] = None,
+ **kwargs,
+):
+ """
+ Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles
+ custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`.
+
+ Args:
+ scheduler (`SchedulerMixin`):
+ The scheduler to get timesteps from.
+ num_inference_steps (`int`):
+ The number of diffusion steps used when generating samples with a pre-trained model. If used, `timesteps`
+ must be `None`.
+ device (`str` or `torch.device`, *optional*):
+ The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
+ timesteps (`List[int]`, *optional*):
+ Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed,
+ `num_inference_steps` and `sigmas` must be `None`.
+ sigmas (`List[float]`, *optional*):
+ Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed,
+ `num_inference_steps` and `timesteps` must be `None`.
+
+ Returns:
+ `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the
+ second element is the number of inference steps.
+ """
+ if timesteps is not None and sigmas is not None:
+ raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values")
+ if timesteps is not None:
+ accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
+ if not accepts_timesteps:
+ raise ValueError(
+ f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
+ f" timestep schedules. Please check whether you are using the correct scheduler."
+ )
+ scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
+ timesteps = scheduler.timesteps
+ num_inference_steps = len(timesteps)
+ elif sigmas is not None:
+ accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
+ if not accept_sigmas:
+ raise ValueError(
+ f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
+ f" sigmas schedules. Please check whether you are using the correct scheduler."
+ )
+ scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs)
+ timesteps = scheduler.timesteps
+ num_inference_steps = len(timesteps)
+ else:
+ scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
+ timesteps = scheduler.timesteps
+ return timesteps, num_inference_steps
+
+
+@synchronize_timer('Export to trimesh')
+def export_to_trimesh(mesh_output):
+ if isinstance(mesh_output, list):
+ outputs = []
+ for mesh in mesh_output:
+ if mesh is None:
+ outputs.append(None)
+ else:
+ mesh.mesh_f = mesh.mesh_f[:, ::-1]
+ mesh_output = trimesh.Trimesh(mesh.mesh_v, mesh.mesh_f)
+ outputs.append(mesh_output)
+ return outputs
+ else:
+ mesh_output.mesh_f = mesh_output.mesh_f[:, ::-1]
+ mesh_output = trimesh.Trimesh(mesh_output.mesh_v, mesh_output.mesh_f)
+ return mesh_output
+
+
+def get_obj_from_str(string, reload=False):
+ module, cls = string.rsplit(".", 1)
+ if reload:
+ module_imp = importlib.import_module(module)
+ importlib.reload(module_imp)
+ return getattr(importlib.import_module(module, package=None), cls)
+
+
+def instantiate_from_config(config, **kwargs):
+ if "target" not in config:
+ raise KeyError("Expected key `target` to instantiate.")
+ cls = get_obj_from_str(config["target"])
+ params = config.get("params", dict())
+ kwargs.update(params)
+ instance = cls(**kwargs)
+ return instance
+
+
+class Hunyuan3DDiTPipeline:
+ model_cpu_offload_seq = "conditioner->model->vae"
+ _exclude_from_cpu_offload = []
+
+ @classmethod
+ @synchronize_timer('Hunyuan3DDiTPipeline Model Loading')
+ def from_single_file(
+ cls,
+ ckpt_path,
+ config_path,
+ device='cuda',
+ dtype=torch.float16,
+ use_safetensors=None,
+ **kwargs,
+ ):
+ # load config
+ with open(config_path, 'r') as f:
+ config = yaml.safe_load(f)
+
+ # load ckpt
+ if use_safetensors:
+ ckpt_path = ckpt_path.replace('.ckpt', '.safetensors')
+ if not os.path.exists(ckpt_path):
+ raise FileNotFoundError(f"Model file {ckpt_path} not found")
+ logger.info(f"Loading model from {ckpt_path}")
+
+ if use_safetensors:
+ # parse safetensors
+ import safetensors.torch
+ safetensors_ckpt = safetensors.torch.load_file(ckpt_path, device='cpu')
+ ckpt = {}
+ for key, value in safetensors_ckpt.items():
+ model_name = key.split('.')[0]
+ new_key = key[len(model_name) + 1:]
+ if model_name not in ckpt:
+ ckpt[model_name] = {}
+ ckpt[model_name][new_key] = value
+ else:
+ ckpt = torch.load(ckpt_path, map_location='cpu', weights_only=True)
+ # load model
+ model = instantiate_from_config(config['model'])
+ model.load_state_dict(ckpt['model'])
+ vae = instantiate_from_config(config['vae'])
+ vae.load_state_dict(ckpt['vae'], strict=False)
+ conditioner = instantiate_from_config(config['conditioner'])
+ if 'conditioner' in ckpt:
+ conditioner.load_state_dict(ckpt['conditioner'])
+ image_processor = instantiate_from_config(config['image_processor'])
+ scheduler = instantiate_from_config(config['scheduler'])
+
+ model_kwargs = dict(
+ vae=vae,
+ model=model,
+ scheduler=scheduler,
+ conditioner=conditioner,
+ image_processor=image_processor,
+ device=device,
+ dtype=dtype,
+ )
+ model_kwargs.update(kwargs)
+
+ return cls(
+ **model_kwargs
+ )
+
+ @classmethod
+ def from_pretrained(
+ cls,
+ model_path,
+ device='cuda',
+ dtype=torch.float16,
+ use_safetensors=False,
+ variant='fp16',
+ subfolder='hunyuan3d-dit-v2-1',
+ **kwargs,
+ ):
+ kwargs['from_pretrained_kwargs'] = dict(
+ model_path=model_path,
+ subfolder=subfolder,
+ use_safetensors=use_safetensors,
+ variant=variant,
+ dtype=dtype,
+ device=device,
+ )
+ config_path, ckpt_path = smart_load_model(
+ model_path,
+ subfolder=subfolder,
+ use_safetensors=use_safetensors,
+ variant=variant
+ )
+ return cls.from_single_file(
+ ckpt_path,
+ config_path,
+ device=device,
+ dtype=dtype,
+ use_safetensors=use_safetensors,
+ **kwargs
+ )
+
+ def __init__(
+ self,
+ vae,
+ model,
+ scheduler,
+ conditioner,
+ image_processor,
+ device='cuda',
+ dtype=torch.float16,
+ **kwargs
+ ):
+ self.vae = vae
+ self.model = model
+ self.scheduler = scheduler
+ self.conditioner = conditioner
+ self.image_processor = image_processor
+ self.kwargs = kwargs
+ self.to(device, dtype)
+
+ def compile(self):
+ self.vae = torch.compile(self.vae)
+ self.model = torch.compile(self.model)
+ self.conditioner = torch.compile(self.conditioner)
+
+ def enable_flashvdm(
+ self,
+ enabled: bool = True,
+ adaptive_kv_selection=True,
+ topk_mode='mean',
+ mc_algo='mc',
+ replace_vae=True,
+ ):
+ if enabled:
+ model_path = self.kwargs['from_pretrained_kwargs']['model_path']
+ turbo_vae_mapping = {
+ 'Hunyuan3D-2': ('tencent/Hunyuan3D-2', 'hunyuan3d-vae-v2-0-turbo'),
+ 'Hunyuan3D-2mv': ('tencent/Hunyuan3D-2', 'hunyuan3d-vae-v2-0-turbo'),
+ 'Hunyuan3D-2mini': ('tencent/Hunyuan3D-2mini', 'hunyuan3d-vae-v2-mini-turbo'),
+ }
+ model_name = model_path.split('/')[-1]
+ if replace_vae and model_name in turbo_vae_mapping:
+ model_path, subfolder = turbo_vae_mapping[model_name]
+ self.vae = ShapeVAE.from_pretrained(
+ model_path, subfolder=subfolder,
+ use_safetensors=self.kwargs['from_pretrained_kwargs']['use_safetensors'],
+ device=self.device,
+ )
+ self.vae.enable_flashvdm_decoder(
+ enabled=enabled,
+ adaptive_kv_selection=adaptive_kv_selection,
+ topk_mode=topk_mode,
+ mc_algo=mc_algo
+ )
+ else:
+ model_path = self.kwargs['from_pretrained_kwargs']['model_path']
+ vae_mapping = {
+ 'Hunyuan3D-2': ('tencent/Hunyuan3D-2', 'hunyuan3d-vae-v2-0'),
+ 'Hunyuan3D-2mv': ('tencent/Hunyuan3D-2', 'hunyuan3d-vae-v2-0'),
+ 'Hunyuan3D-2mini': ('tencent/Hunyuan3D-2mini', 'hunyuan3d-vae-v2-mini'),
+ }
+ model_name = model_path.split('/')[-1]
+ if model_name in vae_mapping:
+ model_path, subfolder = vae_mapping[model_name]
+ self.vae = ShapeVAE.from_pretrained(model_path, subfolder=subfolder)
+ self.vae.enable_flashvdm_decoder(enabled=False)
+
+ def to(self, device=None, dtype=None):
+ if dtype is not None:
+ self.dtype = dtype
+ self.vae.to(dtype=dtype)
+ self.model.to(dtype=dtype)
+ self.conditioner.to(dtype=dtype)
+ if device is not None:
+ self.device = torch.device(device)
+ self.vae.to(device)
+ self.model.to(device)
+ self.conditioner.to(device)
+
+ @property
+ def _execution_device(self):
+ r"""
+ Returns the device on which the pipeline's models will be executed. After calling
+ [`~DiffusionPipeline.enable_sequential_cpu_offload`] the execution device can only be inferred from
+ Accelerate's module hooks.
+ """
+ for name, model in self.components.items():
+ if not isinstance(model, torch.nn.Module) or name in self._exclude_from_cpu_offload:
+ continue
+
+ if not hasattr(model, "_hf_hook"):
+ return self.device
+ for module in model.modules():
+ if (
+ hasattr(module, "_hf_hook")
+ and hasattr(module._hf_hook, "execution_device")
+ and module._hf_hook.execution_device is not None
+ ):
+ return torch.device(module._hf_hook.execution_device)
+ return self.device
+
+ def enable_model_cpu_offload(self, gpu_id: Optional[int] = None, device: Union[torch.device, str] = "cuda"):
+ r"""
+ Offloads all models to CPU using accelerate, reducing memory usage with a low impact on performance. Compared
+ to `enable_sequential_cpu_offload`, this method moves one whole model at a time to the GPU when its `forward`
+ method is called, and the model remains in GPU until the next model runs. Memory savings are lower than with
+ `enable_sequential_cpu_offload`, but performance is much better due to the iterative execution of the `unet`.
+
+ Arguments:
+ gpu_id (`int`, *optional*):
+ The ID of the accelerator that shall be used in inference. If not specified, it will default to 0.
+ device (`torch.Device` or `str`, *optional*, defaults to "cuda"):
+ The PyTorch device type of the accelerator that shall be used in inference. If not specified, it will
+ default to "cuda".
+ """
+ if self.model_cpu_offload_seq is None:
+ raise ValueError(
+ "Model CPU offload cannot be enabled because no `model_cpu_offload_seq` class attribute is set."
+ )
+
+ if is_accelerate_available() and is_accelerate_version(">=", "0.17.0.dev0"):
+ from accelerate import cpu_offload_with_hook
+ else:
+ raise ImportError("`enable_model_cpu_offload` requires `accelerate v0.17.0` or higher.")
+
+ torch_device = torch.device(device)
+ device_index = torch_device.index
+
+ if gpu_id is not None and device_index is not None:
+ raise ValueError(
+ f"You have passed both `gpu_id`={gpu_id} and an index as part of the passed device `device`={device}"
+ f"Cannot pass both. Please make sure to either not define `gpu_id` or not pass the index as part of "
+ f"the device: `device`={torch_device.type}"
+ )
+
+ # _offload_gpu_id should be set to passed gpu_id (or id in passed `device`)
+ # or default to previously set id or default to 0
+ self._offload_gpu_id = gpu_id or torch_device.index or getattr(self, "_offload_gpu_id", 0)
+
+ device_type = torch_device.type
+ device = torch.device(f"{device_type}:{self._offload_gpu_id}")
+
+ if self.device.type != "cpu":
+ self.to("cpu")
+ device_mod = getattr(torch, self.device.type, None)
+ if hasattr(device_mod, "empty_cache") and device_mod.is_available():
+ device_mod.empty_cache()
+ # otherwise we don't see the memory savings (but they probably exist)
+
+ all_model_components = {k: v for k, v in self.components.items() if isinstance(v, torch.nn.Module)}
+
+ self._all_hooks = []
+ hook = None
+ for model_str in self.model_cpu_offload_seq.split("->"):
+ model = all_model_components.pop(model_str, None)
+ if not isinstance(model, torch.nn.Module):
+ continue
+
+ _, hook = cpu_offload_with_hook(model, device, prev_module_hook=hook)
+ self._all_hooks.append(hook)
+
+ # CPU offload models that are not in the seq chain unless they are explicitly excluded
+ # these models will stay on CPU until maybe_free_model_hooks is called
+ # some models cannot be in the seq chain because they are iteratively called,
+ # such as controlnet
+ for name, model in all_model_components.items():
+ if not isinstance(model, torch.nn.Module):
+ continue
+
+ if name in self._exclude_from_cpu_offload:
+ model.to(device)
+ else:
+ _, hook = cpu_offload_with_hook(model, device)
+ self._all_hooks.append(hook)
+
+ def maybe_free_model_hooks(self):
+ r"""
+ Function that offloads all components, removes all model hooks that were added when using
+ `enable_model_cpu_offload` and then applies them again. In case the model has not been offloaded this function
+ is a no-op. Make sure to add this function to the end of the `__call__` function of your pipeline so that it
+ functions correctly when applying enable_model_cpu_offload.
+ """
+ if not hasattr(self, "_all_hooks") or len(self._all_hooks) == 0:
+ # `enable_model_cpu_offload` has not be called, so silently do nothing
+ return
+
+ for hook in self._all_hooks:
+ # offload model and remove hook from model
+ hook.offload()
+ hook.remove()
+
+ # make sure the model is in the same state as before calling it
+ self.enable_model_cpu_offload()
+
+ @synchronize_timer('Encode cond')
+ def encode_cond(self, image, additional_cond_inputs, do_classifier_free_guidance, dual_guidance):
+ bsz = image.shape[0]
+ cond = self.conditioner(image=image, **additional_cond_inputs)
+
+ if do_classifier_free_guidance:
+ un_cond = self.conditioner.unconditional_embedding(bsz, **additional_cond_inputs)
+
+ if dual_guidance:
+ un_cond_drop_main = copy.deepcopy(un_cond)
+ un_cond_drop_main['additional'] = cond['additional']
+
+ def cat_recursive(a, b, c):
+ if isinstance(a, torch.Tensor):
+ return torch.cat([a, b, c], dim=0).to(self.dtype)
+ out = {}
+ for k in a.keys():
+ out[k] = cat_recursive(a[k], b[k], c[k])
+ return out
+
+ cond = cat_recursive(cond, un_cond_drop_main, un_cond)
+ else:
+ def cat_recursive(a, b):
+ if isinstance(a, torch.Tensor):
+ return torch.cat([a, b], dim=0).to(self.dtype)
+ out = {}
+ for k in a.keys():
+ out[k] = cat_recursive(a[k], b[k])
+ return out
+
+ cond = cat_recursive(cond, un_cond)
+ return cond
+
+ def prepare_extra_step_kwargs(self, generator, eta):
+ # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
+ # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
+ # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
+ # and should be between [0, 1]
+
+ accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys())
+ extra_step_kwargs = {}
+ if accepts_eta:
+ extra_step_kwargs["eta"] = eta
+
+ # check if the scheduler accepts generator
+ accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys())
+ if accepts_generator:
+ extra_step_kwargs["generator"] = generator
+ return extra_step_kwargs
+
+ def prepare_latents(self, batch_size, dtype, device, generator, latents=None):
+ shape = (batch_size, *self.vae.latent_shape)
+ if isinstance(generator, list) and len(generator) != batch_size:
+ raise ValueError(
+ f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
+ f" size of {batch_size}. Make sure the batch size matches the length of the generators."
+ )
+
+ if latents is None:
+ latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
+ else:
+ latents = latents.to(device)
+
+ # scale the initial noise by the standard deviation required by the scheduler
+ latents = latents * getattr(self.scheduler, 'init_noise_sigma', 1.0)
+ return latents
+
+ def prepare_image(self, image, mask=None) -> dict:
+ if isinstance(image, torch.Tensor) and isinstance(mask, torch.Tensor):
+ outputs = {
+ 'image': image,
+ 'mask': mask
+ }
+ return outputs
+
+ if isinstance(image, str) and not os.path.exists(image):
+ raise FileNotFoundError(f"Couldn't find image at path {image}")
+
+ if not isinstance(image, list):
+ image = [image]
+
+ outputs = []
+ for img in image:
+ output = self.image_processor(img)
+ outputs.append(output)
+
+ cond_input = {k: [] for k in outputs[0].keys()}
+ for output in outputs:
+ for key, value in output.items():
+ cond_input[key].append(value)
+ for key, value in cond_input.items():
+ if isinstance(value[0], torch.Tensor):
+ cond_input[key] = torch.cat(value, dim=0)
+
+ return cond_input
+
+ def get_guidance_scale_embedding(self, w, embedding_dim=512, dtype=torch.float32):
+ """
+ See https://github.com/google-research/vdm/blob/dc27b98a554f65cdc654b800da5aa1846545d41b/model_vdm.py#L298
+
+ Args:
+ timesteps (`torch.Tensor`):
+ generate embedding vectors at these timesteps
+ embedding_dim (`int`, *optional*, defaults to 512):
+ dimension of the embeddings to generate
+ dtype:
+ data type of the generated embeddings
+
+ Returns:
+ `torch.FloatTensor`: Embedding vectors with shape `(len(timesteps), embedding_dim)`
+ """
+ assert len(w.shape) == 1
+ w = w * 1000.0
+
+ half_dim = embedding_dim // 2
+ emb = torch.log(torch.tensor(10000.0)) / (half_dim - 1)
+ emb = torch.exp(torch.arange(half_dim, dtype=dtype) * -emb)
+ emb = w.to(dtype)[:, None] * emb[None, :]
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
+ if embedding_dim % 2 == 1: # zero pad
+ emb = torch.nn.functional.pad(emb, (0, 1))
+ assert emb.shape == (w.shape[0], embedding_dim)
+ return emb
+
+ def set_surface_extractor(self, mc_algo):
+ if mc_algo is None:
+ return
+ logger.info('The parameters `mc_algo` is deprecated, and will be removed in future versions.\n'
+ 'Please use: \n'
+ 'from hy3dshape.models.autoencoders import SurfaceExtractors\n'
+ 'pipeline.vae.surface_extractor = SurfaceExtractors[mc_algo]() instead\n')
+ if mc_algo not in SurfaceExtractors.keys():
+ raise ValueError(f"Unknown mc_algo {mc_algo}")
+ self.vae.surface_extractor = SurfaceExtractors[mc_algo]()
+
+ @torch.no_grad()
+ def __call__(
+ self,
+ image: Union[str, List[str], Image.Image] = None,
+ num_inference_steps: int = 50,
+ timesteps: List[int] = None,
+ sigmas: List[float] = None,
+ eta: float = 0.0,
+ guidance_scale: float = 7.5,
+ dual_guidance_scale: float = 10.5,
+ dual_guidance: bool = True,
+ generator=None,
+ box_v=1.01,
+ octree_resolution=384,
+ mc_level=-1 / 512,
+ num_chunks=8000,
+ mc_algo=None,
+ output_type: Optional[str] = "trimesh",
+ enable_pbar=True,
+ **kwargs,
+ ) -> List[List[trimesh.Trimesh]]:
+ callback = kwargs.pop("callback", None)
+ callback_steps = kwargs.pop("callback_steps", None)
+
+ self.set_surface_extractor(mc_algo)
+
+ device = self.device
+ dtype = self.dtype
+ do_classifier_free_guidance = guidance_scale >= 0 and \
+ getattr(self.model, 'guidance_cond_proj_dim', None) is None
+ dual_guidance = dual_guidance_scale >= 0 and dual_guidance
+
+ if isinstance(image, torch.Tensor):
+ pass
+ else:
+ cond_inputs = self.prepare_image(image)
+ image = cond_inputs.pop('image')
+
+ cond = self.encode_cond(
+ image=image,
+ additional_cond_inputs=cond_inputs,
+ do_classifier_free_guidance=do_classifier_free_guidance,
+ dual_guidance=False,
+ )
+ batch_size = image.shape[0]
+
+ t_dtype = torch.long
+ inner_scheduler = copy.deepcopy(self.scheduler)
+ timesteps, num_inference_steps = retrieve_timesteps(
+ inner_scheduler, num_inference_steps, device, timesteps, sigmas)
+
+ latents = self.prepare_latents(batch_size, dtype, device, generator)
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
+
+ guidance_cond = None
+ if getattr(self.model, 'guidance_cond_proj_dim', None) is not None:
+ logger.info('Using lcm guidance scale')
+ guidance_scale_tensor = torch.tensor(guidance_scale - 1).repeat(batch_size)
+ guidance_cond = self.get_guidance_scale_embedding(
+ guidance_scale_tensor, embedding_dim=self.model.guidance_cond_proj_dim
+ ).to(device=device, dtype=latents.dtype)
+ with synchronize_timer('Diffusion Sampling'):
+ for i, t in enumerate(tqdm(timesteps, disable=not enable_pbar, desc="Diffusion Sampling:", leave=False)):
+ # expand the latents if we are doing classifier free guidance
+ if do_classifier_free_guidance:
+ latent_model_input = torch.cat([latents] * (3 if dual_guidance else 2))
+ else:
+ latent_model_input = latents
+ latent_model_input = inner_scheduler.scale_model_input(latent_model_input, t)
+
+ # predict the noise residual
+ timestep_tensor = torch.tensor([t], dtype=t_dtype, device=device)
+ timestep_tensor = timestep_tensor.expand(latent_model_input.shape[0])
+ noise_pred = self.model(latent_model_input, timestep_tensor, cond, guidance_cond=guidance_cond)
+
+ # no drop, drop clip, all drop
+ if do_classifier_free_guidance:
+ if dual_guidance:
+ noise_pred_clip, noise_pred_dino, noise_pred_uncond = noise_pred.chunk(3)
+ noise_pred = (
+ noise_pred_uncond
+ + guidance_scale * (noise_pred_clip - noise_pred_dino)
+ + dual_guidance_scale * (noise_pred_dino - noise_pred_uncond)
+ )
+ else:
+ noise_pred_cond, noise_pred_uncond = noise_pred.chunk(2)
+ noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_cond - noise_pred_uncond)
+
+ # compute the previous noisy sample x_t -> x_t-1
+ outputs = inner_scheduler.step(noise_pred, t, latents, **extra_step_kwargs)
+ latents = outputs.prev_sample
+
+ if callback is not None and i % callback_steps == 0:
+ step_idx = i // getattr(inner_scheduler, "order", 1)
+ callback(step_idx, t, outputs)
+
+ return self._export(
+ latents,
+ output_type,
+ box_v, mc_level, num_chunks, octree_resolution, mc_algo,
+ )
+
+ def _export(
+ self,
+ latents,
+ output_type='trimesh',
+ box_v=1.01,
+ mc_level=0.0,
+ num_chunks=20000,
+ octree_resolution=256,
+ mc_algo='mc',
+ enable_pbar=True
+ ):
+ if not output_type == "latent":
+ latents = 1. / self.vae.scale_factor * latents
+ latents = self.vae(latents)
+ outputs = self.vae.latents2mesh(
+ latents,
+ bounds=box_v,
+ mc_level=mc_level,
+ num_chunks=num_chunks,
+ octree_resolution=octree_resolution,
+ mc_algo=mc_algo,
+ enable_pbar=enable_pbar,
+ )
+ else:
+ outputs = latents
+
+ if output_type == 'trimesh':
+ outputs = export_to_trimesh(outputs)
+
+ return outputs
+
+
+class Hunyuan3DDiTFlowMatchingPipeline(Hunyuan3DDiTPipeline):
+
+ @torch.inference_mode()
+ def __call__(
+ self,
+ image: Union[str, List[str], Image.Image, dict, List[dict], torch.Tensor] = None,
+ num_inference_steps: int = 50,
+ timesteps: List[int] = None,
+ sigmas: List[float] = None,
+ eta: float = 0.0,
+ guidance_scale: float = 5.0,
+ generator=None,
+ box_v=1.01,
+ octree_resolution=384,
+ mc_level=0.0,
+ mc_algo=None,
+ num_chunks=8000,
+ output_type: Optional[str] = "trimesh",
+ enable_pbar=True,
+ mask = None,
+ **kwargs,
+ ) -> List[List[trimesh.Trimesh]]:
+ callback = kwargs.pop("callback", None)
+ callback_steps = kwargs.pop("callback_steps", None)
+
+ self.set_surface_extractor(mc_algo)
+
+ device = self.device
+ dtype = self.dtype
+ do_classifier_free_guidance = guidance_scale >= 0 and not (
+ hasattr(self.model, 'guidance_embed') and
+ self.model.guidance_embed is True
+ )
+
+ # print('image', type(image), 'mask', type(mask))
+ cond_inputs = self.prepare_image(image, mask)
+ image = cond_inputs.pop('image')
+ cond = self.encode_cond(
+ image=image,
+ additional_cond_inputs=cond_inputs,
+ do_classifier_free_guidance=do_classifier_free_guidance,
+ dual_guidance=False,
+ )
+
+ batch_size = image.shape[0]
+
+ inner_scheduler = copy.deepcopy(self.scheduler)
+
+ # 5. Prepare timesteps
+ # NOTE: this is slightly different from common usage, we start from 0.
+ sigmas = np.linspace(0, 1, num_inference_steps) if sigmas is None else sigmas
+ timesteps, num_inference_steps = retrieve_timesteps(
+ inner_scheduler,
+ num_inference_steps,
+ device,
+ sigmas=sigmas,
+ )
+ latents = self.prepare_latents(batch_size, dtype, device, generator)
+
+ guidance = None
+ if hasattr(self.model, 'guidance_embed') and \
+ self.model.guidance_embed is True:
+ guidance = torch.tensor([guidance_scale] * batch_size, device=device, dtype=dtype)
+ # logger.info(f'Using guidance embed with scale {guidance_scale}')
+
+ with synchronize_timer('Diffusion Sampling'):
+ for i, t in enumerate(tqdm(timesteps, disable=not enable_pbar, desc="Diffusion Sampling:")):
+ # expand the latents if we are doing classifier free guidance
+ if do_classifier_free_guidance:
+ latent_model_input = torch.cat([latents] * 2)
+ else:
+ latent_model_input = latents
+
+ # NOTE: we assume model get timesteps ranged from 0 to 1
+ timestep = t.expand(latent_model_input.shape[0]).to(latents.dtype)
+ timestep = timestep / inner_scheduler.config.num_train_timesteps
+ noise_pred = self.model(latent_model_input, timestep, cond, guidance=guidance)
+
+ if do_classifier_free_guidance:
+ noise_pred_cond, noise_pred_uncond = noise_pred.chunk(2)
+ noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_cond - noise_pred_uncond)
+
+ # compute the previous noisy sample x_t -> x_t-1
+ outputs = inner_scheduler.step(noise_pred, t, latents)
+ latents = outputs.prev_sample
+
+ if callback is not None and i % callback_steps == 0:
+ step_idx = i // getattr(inner_scheduler, "order", 1)
+ callback(step_idx, t, outputs)
+
+ del inner_scheduler
+ return self._export(
+ latents,
+ output_type,
+ box_v, mc_level, num_chunks, octree_resolution, mc_algo,
+ enable_pbar=enable_pbar,
+ )
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/postprocessors.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/postprocessors.py
new file mode 100644
index 0000000000000000000000000000000000000000..d258369e2b9116090ade3c955d57215d1481138e
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/postprocessors.py
@@ -0,0 +1,202 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import tempfile
+from typing import Union
+
+import numpy as np
+import pymeshlab
+import torch
+import trimesh
+
+from .models.autoencoders import Latent2MeshOutput
+from .utils import synchronize_timer
+
+
+def load_mesh(path):
+ if path.endswith(".glb"):
+ mesh = trimesh.load(path)
+ else:
+ mesh = pymeshlab.MeshSet()
+ mesh.load_new_mesh(path)
+ return mesh
+
+
+def reduce_face(mesh: pymeshlab.MeshSet, max_facenum: int = 200000):
+ if max_facenum > mesh.current_mesh().face_number():
+ return mesh
+
+ mesh.apply_filter(
+ "meshing_decimation_quadric_edge_collapse",
+ targetfacenum=max_facenum,
+ qualitythr=1.0,
+ preserveboundary=True,
+ boundaryweight=3,
+ preservenormal=True,
+ preservetopology=True,
+ autoclean=True
+ )
+ return mesh
+
+
+def remove_floater(mesh: pymeshlab.MeshSet):
+ mesh.apply_filter("compute_selection_by_small_disconnected_components_per_face",
+ nbfaceratio=0.005)
+ mesh.apply_filter("compute_selection_transfer_face_to_vertex", inclusive=False)
+ mesh.apply_filter("meshing_remove_selected_vertices_and_faces")
+ return mesh
+
+
+def pymeshlab2trimesh(mesh: pymeshlab.MeshSet):
+ with tempfile.NamedTemporaryFile(suffix='.ply', delete=False) as temp_file:
+ mesh.save_current_mesh(temp_file.name)
+ mesh = trimesh.load(temp_file.name)
+ # 检查加载的对象类型
+ if isinstance(mesh, trimesh.Scene):
+ combined_mesh = trimesh.Trimesh()
+ # 如果是Scene,遍历所有的geometry并合并
+ for geom in mesh.geometry.values():
+ combined_mesh = trimesh.util.concatenate([combined_mesh, geom])
+ mesh = combined_mesh
+ return mesh
+
+
+def trimesh2pymeshlab(mesh: trimesh.Trimesh):
+ with tempfile.NamedTemporaryFile(suffix='.ply', delete=False) as temp_file:
+ if isinstance(mesh, trimesh.scene.Scene):
+ for idx, obj in enumerate(mesh.geometry.values()):
+ if idx == 0:
+ temp_mesh = obj
+ else:
+ temp_mesh = temp_mesh + obj
+ mesh = temp_mesh
+ mesh.export(temp_file.name)
+ mesh = pymeshlab.MeshSet()
+ mesh.load_new_mesh(temp_file.name)
+ return mesh
+
+
+def export_mesh(input, output):
+ if isinstance(input, pymeshlab.MeshSet):
+ mesh = output
+ elif isinstance(input, Latent2MeshOutput):
+ output = Latent2MeshOutput()
+ output.mesh_v = output.current_mesh().vertex_matrix()
+ output.mesh_f = output.current_mesh().face_matrix()
+ mesh = output
+ else:
+ mesh = pymeshlab2trimesh(output)
+ return mesh
+
+
+def import_mesh(mesh: Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput, str]) -> pymeshlab.MeshSet:
+ if isinstance(mesh, str):
+ mesh = load_mesh(mesh)
+ elif isinstance(mesh, Latent2MeshOutput):
+ mesh = pymeshlab.MeshSet()
+ mesh_pymeshlab = pymeshlab.Mesh(vertex_matrix=mesh.mesh_v, face_matrix=mesh.mesh_f)
+ mesh.add_mesh(mesh_pymeshlab, "converted_mesh")
+
+ if isinstance(mesh, (trimesh.Trimesh, trimesh.scene.Scene)):
+ mesh = trimesh2pymeshlab(mesh)
+
+ return mesh
+
+
+class FaceReducer:
+ @synchronize_timer('FaceReducer')
+ def __call__(
+ self,
+ mesh: Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput, str],
+ max_facenum: int = 40000
+ ) -> Union[pymeshlab.MeshSet, trimesh.Trimesh]:
+ ms = import_mesh(mesh)
+ ms = reduce_face(ms, max_facenum=max_facenum)
+ mesh = export_mesh(mesh, ms)
+ return mesh
+
+
+class FloaterRemover:
+ @synchronize_timer('FloaterRemover')
+ def __call__(
+ self,
+ mesh: Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput, str],
+ ) -> Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput]:
+ ms = import_mesh(mesh)
+ ms = remove_floater(ms)
+ mesh = export_mesh(mesh, ms)
+ return mesh
+
+
+class DegenerateFaceRemover:
+ @synchronize_timer('DegenerateFaceRemover')
+ def __call__(
+ self,
+ mesh: Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput, str],
+ ) -> Union[pymeshlab.MeshSet, trimesh.Trimesh, Latent2MeshOutput]:
+ ms = import_mesh(mesh)
+
+ with tempfile.NamedTemporaryFile(suffix='.ply', delete=False) as temp_file:
+ ms.save_current_mesh(temp_file.name)
+ ms = pymeshlab.MeshSet()
+ ms.load_new_mesh(temp_file.name)
+
+ mesh = export_mesh(mesh, ms)
+ return mesh
+
+
+def mesh_normalize(mesh):
+ """
+ Normalize mesh vertices to sphere
+ """
+ scale_factor = 1.2
+ vtx_pos = np.asarray(mesh.vertices)
+ max_bb = (vtx_pos - 0).max(0)[0]
+ min_bb = (vtx_pos - 0).min(0)[0]
+
+ center = (max_bb + min_bb) / 2
+
+ scale = torch.norm(torch.tensor(vtx_pos - center, dtype=torch.float32), dim=1).max() * 2.0
+
+ vtx_pos = (vtx_pos - center) * (scale_factor / float(scale))
+ mesh.vertices = vtx_pos
+
+ return mesh
+
+
+class MeshSimplifier:
+ def __init__(self, executable: str = None):
+ if executable is None:
+ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
+ executable = os.path.join(CURRENT_DIR, "mesh_simplifier.bin")
+ self.executable = executable
+
+ @synchronize_timer('MeshSimplifier')
+ def __call__(
+ self,
+ mesh: Union[trimesh.Trimesh],
+ ) -> Union[trimesh.Trimesh]:
+ with tempfile.NamedTemporaryFile(suffix='.obj', delete=False) as temp_input:
+ with tempfile.NamedTemporaryFile(suffix='.obj', delete=False) as temp_output:
+ mesh.export(temp_input.name)
+ os.system(f'{self.executable} {temp_input.name} {temp_output.name}')
+ ms = trimesh.load(temp_output.name, process=False)
+ if isinstance(ms, trimesh.Scene):
+ combined_mesh = trimesh.Trimesh()
+ for geom in ms.geometry.values():
+ combined_mesh = trimesh.util.concatenate([combined_mesh, geom])
+ ms = combined_mesh
+ ms = mesh_normalize(ms)
+ return ms
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/preprocessors.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/preprocessors.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a9cb9ea1591363fb77f4e02351a0f945e3bc1ab
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/preprocessors.py
@@ -0,0 +1,167 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import cv2
+import numpy as np
+import torch
+from PIL import Image
+from einops import repeat, rearrange
+
+
+def array_to_tensor(np_array):
+ image_pt = torch.tensor(np_array).float()
+ image_pt = image_pt / 255 * 2 - 1
+ image_pt = rearrange(image_pt, "h w c -> c h w")
+ image_pts = repeat(image_pt, "c h w -> b c h w", b=1)
+ return image_pts
+
+
+class ImageProcessorV2:
+ def __init__(self, size=512, border_ratio=None):
+ self.size = size
+ self.border_ratio = border_ratio
+
+ @staticmethod
+ def recenter(image, border_ratio: float = 0.2):
+ """ recenter an image to leave some empty space at the image border.
+
+ Args:
+ image (ndarray): input image, float/uint8 [H, W, 3/4]
+ mask (ndarray): alpha mask, bool [H, W]
+ border_ratio (float, optional): border ratio, image will be resized to (1 - border_ratio). Defaults to 0.2.
+
+ Returns:
+ ndarray: output image, float/uint8 [H, W, 3/4]
+ """
+
+ if image.shape[-1] == 4:
+ mask = image[..., 3]
+ else:
+ mask = np.ones_like(image[..., 0:1]) * 255
+ image = np.concatenate([image, mask], axis=-1)
+ mask = mask[..., 0]
+
+ H, W, C = image.shape
+
+ size = max(H, W)
+ result = np.zeros((size, size, C), dtype=np.uint8)
+
+ coords = np.nonzero(mask)
+ x_min, x_max = coords[0].min(), coords[0].max()
+ y_min, y_max = coords[1].min(), coords[1].max()
+ h = x_max - x_min
+ w = y_max - y_min
+ if h == 0 or w == 0:
+ raise ValueError('input image is empty')
+ desired_size = int(size * (1 - border_ratio))
+ scale = desired_size / max(h, w)
+ h2 = int(h * scale)
+ w2 = int(w * scale)
+ x2_min = (size - h2) // 2
+ x2_max = x2_min + h2
+
+ y2_min = (size - w2) // 2
+ y2_max = y2_min + w2
+
+ result[x2_min:x2_max, y2_min:y2_max] = cv2.resize(image[x_min:x_max, y_min:y_max], (w2, h2),
+ interpolation=cv2.INTER_AREA)
+
+ bg = np.ones((result.shape[0], result.shape[1], 3), dtype=np.uint8) * 255
+
+ mask = result[..., 3:].astype(np.float32) / 255
+ result = result[..., :3] * mask + bg * (1 - mask)
+
+ mask = mask * 255
+ result = result.clip(0, 255).astype(np.uint8)
+ mask = mask.clip(0, 255).astype(np.uint8)
+ return result, mask
+
+ def load_image(self, image, border_ratio=0.15, to_tensor=True):
+ if isinstance(image, str):
+ image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
+ image, mask = self.recenter(image, border_ratio=border_ratio)
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
+ elif isinstance(image, Image.Image):
+ image = image.convert("RGBA")
+ image = np.asarray(image)
+ image, mask = self.recenter(image, border_ratio=border_ratio)
+
+ image = cv2.resize(image, (self.size, self.size), interpolation=cv2.INTER_CUBIC)
+ mask = cv2.resize(mask, (self.size, self.size), interpolation=cv2.INTER_NEAREST)
+ mask = mask[..., np.newaxis]
+
+ if to_tensor:
+ image = array_to_tensor(image)
+ mask = array_to_tensor(mask)
+ return image, mask
+
+ def __call__(self, image, border_ratio=0.15, to_tensor=True, **kwargs):
+ if self.border_ratio is not None:
+ border_ratio = self.border_ratio
+ image, mask = self.load_image(image, border_ratio=border_ratio, to_tensor=to_tensor)
+ outputs = {
+ 'image': image,
+ 'mask': mask
+ }
+ return outputs
+
+
+class MVImageProcessorV2(ImageProcessorV2):
+ """
+ view order: front, front clockwise 90, back, front clockwise 270
+ """
+ return_view_idx = True
+
+ def __init__(self, size=512, border_ratio=None):
+ super().__init__(size, border_ratio)
+ self.view2idx = {
+ 'front': 0,
+ 'left': 1,
+ 'back': 2,
+ 'right': 3
+ }
+
+ def __call__(self, image_dict, border_ratio=0.15, to_tensor=True, **kwargs):
+ if self.border_ratio is not None:
+ border_ratio = self.border_ratio
+
+ images = []
+ masks = []
+ view_idxs = []
+ for idx, (view_tag, image) in enumerate(image_dict.items()):
+ view_idxs.append(self.view2idx[view_tag])
+ image, mask = self.load_image(image, border_ratio=border_ratio, to_tensor=to_tensor)
+ images.append(image)
+ masks.append(mask)
+
+ zipped_lists = zip(view_idxs, images, masks)
+ sorted_zipped_lists = sorted(zipped_lists)
+ view_idxs, images, masks = zip(*sorted_zipped_lists)
+
+ image = torch.cat(images, 0).unsqueeze(0)
+ mask = torch.cat(masks, 0).unsqueeze(0)
+ outputs = {
+ 'image': image,
+ 'mask': mask,
+ 'view_idxs': view_idxs
+ }
+ return outputs
+
+
+IMAGE_PROCESSORS = {
+ "v2": ImageProcessorV2,
+ 'mv_v2': MVImageProcessorV2,
+}
+
+DEFAULT_IMAGEPROCESSOR = 'v2'
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/rembg.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/rembg.py
new file mode 100644
index 0000000000000000000000000000000000000000..6247f060c9f325b1e267668baf236ec8e4c2dae9
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/rembg.py
@@ -0,0 +1,25 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from PIL import Image
+from rembg import remove, new_session
+
+
+class BackgroundRemover():
+ def __init__(self):
+ self.session = new_session()
+
+ def __call__(self, image: Image.Image):
+ output = remove(image, session=self.session, bgcolor=[255, 255, 255, 0])
+ return output
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/schedulers.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/schedulers.py
new file mode 100644
index 0000000000000000000000000000000000000000..13f0da86b278679d427498128392a7a1ad69b2e6
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/schedulers.py
@@ -0,0 +1,480 @@
+# Copyright 2024 Stability AI, Katherine Crowson and The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import math
+from dataclasses import dataclass
+from typing import List, Optional, Tuple, Union
+
+import numpy as np
+import torch
+from diffusers.configuration_utils import ConfigMixin, register_to_config
+from diffusers.schedulers.scheduling_utils import SchedulerMixin
+from diffusers.utils import BaseOutput, logging
+
+logger = logging.get_logger(__name__) # pylint: disable=invalid-name
+
+
+@dataclass
+class FlowMatchEulerDiscreteSchedulerOutput(BaseOutput):
+ """
+ Output class for the scheduler's `step` function output.
+
+ Args:
+ prev_sample (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)` for images):
+ Computed sample `(x_{t-1})` of previous timestep. `prev_sample` should be used as next model input in the
+ denoising loop.
+ """
+
+ prev_sample: torch.FloatTensor
+
+
+class FlowMatchEulerDiscreteScheduler(SchedulerMixin, ConfigMixin):
+ """
+ NOTE: this is very similar to diffusers.FlowMatchEulerDiscreteScheduler. Except our timesteps are reversed
+
+ Euler scheduler.
+
+ This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic
+ methods the library implements for all schedulers such as loading and saving.
+
+ Args:
+ num_train_timesteps (`int`, defaults to 1000):
+ The number of diffusion steps to train the model.
+ timestep_spacing (`str`, defaults to `"linspace"`):
+ The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and
+ Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.
+ shift (`float`, defaults to 1.0):
+ The shift value for the timestep schedule.
+ """
+
+ _compatibles = []
+ order = 1
+
+ @register_to_config
+ def __init__(
+ self,
+ num_train_timesteps: int = 1000,
+ shift: float = 1.0,
+ use_dynamic_shifting=False,
+ ):
+ timesteps = np.linspace(1, num_train_timesteps, num_train_timesteps, dtype=np.float32).copy()
+ timesteps = torch.from_numpy(timesteps).to(dtype=torch.float32)
+
+ sigmas = timesteps / num_train_timesteps
+ if not use_dynamic_shifting:
+ # when use_dynamic_shifting is True, we apply the timestep shifting on the fly based on the image resolution
+ sigmas = shift * sigmas / (1 + (shift - 1) * sigmas)
+
+ self.timesteps = sigmas * num_train_timesteps
+
+ self._step_index = None
+ self._begin_index = None
+
+ self.sigmas = sigmas.to("cpu") # to avoid too much CPU/GPU communication
+ self.sigma_min = self.sigmas[-1].item()
+ self.sigma_max = self.sigmas[0].item()
+
+ @property
+ def step_index(self):
+ """
+ The index counter for current timestep. It will increase 1 after each scheduler step.
+ """
+ return self._step_index
+
+ @property
+ def begin_index(self):
+ """
+ The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
+ """
+ return self._begin_index
+
+ # Copied from diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler.set_begin_index
+ def set_begin_index(self, begin_index: int = 0):
+ """
+ Sets the begin index for the scheduler. This function should be run from pipeline before the inference.
+
+ Args:
+ begin_index (`int`):
+ The begin index for the scheduler.
+ """
+ self._begin_index = begin_index
+
+ def scale_noise(
+ self,
+ sample: torch.FloatTensor,
+ timestep: Union[float, torch.FloatTensor],
+ noise: Optional[torch.FloatTensor] = None,
+ ) -> torch.FloatTensor:
+ """
+ Forward process in flow-matching
+
+ Args:
+ sample (`torch.FloatTensor`):
+ The input sample.
+ timestep (`int`, *optional*):
+ The current timestep in the diffusion chain.
+
+ Returns:
+ `torch.FloatTensor`:
+ A scaled input sample.
+ """
+ # Make sure sigmas and timesteps have the same device and dtype as original_samples
+ sigmas = self.sigmas.to(device=sample.device, dtype=sample.dtype)
+
+ if sample.device.type == "mps" and torch.is_floating_point(timestep):
+ # mps does not support float64
+ schedule_timesteps = self.timesteps.to(sample.device, dtype=torch.float32)
+ timestep = timestep.to(sample.device, dtype=torch.float32)
+ else:
+ schedule_timesteps = self.timesteps.to(sample.device)
+ timestep = timestep.to(sample.device)
+
+ # self.begin_index is None when scheduler is used for training, or pipeline does not implement set_begin_index
+ if self.begin_index is None:
+ step_indices = [self.index_for_timestep(t, schedule_timesteps) for t in timestep]
+ elif self.step_index is not None:
+ # add_noise is called after first denoising step (for inpainting)
+ step_indices = [self.step_index] * timestep.shape[0]
+ else:
+ # add noise is called before first denoising step to create initial latent(img2img)
+ step_indices = [self.begin_index] * timestep.shape[0]
+
+ sigma = sigmas[step_indices].flatten()
+ while len(sigma.shape) < len(sample.shape):
+ sigma = sigma.unsqueeze(-1)
+
+ sample = sigma * noise + (1.0 - sigma) * sample
+
+ return sample
+
+ def _sigma_to_t(self, sigma):
+ return sigma * self.config.num_train_timesteps
+
+ def time_shift(self, mu: float, sigma: float, t: torch.Tensor):
+ return math.exp(mu) / (math.exp(mu) + (1 / t - 1) ** sigma)
+
+ def set_timesteps(
+ self,
+ num_inference_steps: int = None,
+ device: Union[str, torch.device] = None,
+ sigmas: Optional[List[float]] = None,
+ mu: Optional[float] = None,
+ ):
+ """
+ Sets the discrete timesteps used for the diffusion chain (to be run before inference).
+
+ Args:
+ num_inference_steps (`int`):
+ The number of diffusion steps used when generating samples with a pre-trained model.
+ device (`str` or `torch.device`, *optional*):
+ The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
+ """
+
+ if self.config.use_dynamic_shifting and mu is None:
+ raise ValueError(" you have a pass a value for `mu` when `use_dynamic_shifting` is set to be `True`")
+
+ if sigmas is None:
+ self.num_inference_steps = num_inference_steps
+ timesteps = np.linspace(
+ self._sigma_to_t(self.sigma_max), self._sigma_to_t(self.sigma_min), num_inference_steps
+ )
+
+ sigmas = timesteps / self.config.num_train_timesteps
+
+ if self.config.use_dynamic_shifting:
+ sigmas = self.time_shift(mu, 1.0, sigmas)
+ else:
+ sigmas = self.config.shift * sigmas / (1 + (self.config.shift - 1) * sigmas)
+
+ sigmas = torch.from_numpy(sigmas).to(dtype=torch.float32, device=device)
+ timesteps = sigmas * self.config.num_train_timesteps
+
+ self.timesteps = timesteps.to(device=device)
+ self.sigmas = torch.cat([sigmas, torch.ones(1, device=sigmas.device)])
+
+ self._step_index = None
+ self._begin_index = None
+
+ def index_for_timestep(self, timestep, schedule_timesteps=None):
+ if schedule_timesteps is None:
+ schedule_timesteps = self.timesteps
+
+ indices = (schedule_timesteps == timestep).nonzero()
+
+ # The sigma index that is taken for the **very** first `step`
+ # is always the second index (or the last index if there is only 1)
+ # This way we can ensure we don't accidentally skip a sigma in
+ # case we start in the middle of the denoising schedule (e.g. for image-to-image)
+ pos = 1 if len(indices) > 1 else 0
+
+ return indices[pos].item()
+
+ def _init_step_index(self, timestep):
+ if self.begin_index is None:
+ if isinstance(timestep, torch.Tensor):
+ timestep = timestep.to(self.timesteps.device)
+ self._step_index = self.index_for_timestep(timestep)
+ else:
+ self._step_index = self._begin_index
+
+ def step(
+ self,
+ model_output: torch.FloatTensor,
+ timestep: Union[float, torch.FloatTensor],
+ sample: torch.FloatTensor,
+ s_churn: float = 0.0,
+ s_tmin: float = 0.0,
+ s_tmax: float = float("inf"),
+ s_noise: float = 1.0,
+ generator: Optional[torch.Generator] = None,
+ return_dict: bool = True,
+ ) -> Union[FlowMatchEulerDiscreteSchedulerOutput, Tuple]:
+ """
+ Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion
+ process from the learned model outputs (most often the predicted noise).
+
+ Args:
+ model_output (`torch.FloatTensor`):
+ The direct output from learned diffusion model.
+ timestep (`float`):
+ The current discrete timestep in the diffusion chain.
+ sample (`torch.FloatTensor`):
+ A current instance of a sample created by the diffusion process.
+ s_churn (`float`):
+ s_tmin (`float`):
+ s_tmax (`float`):
+ s_noise (`float`, defaults to 1.0):
+ Scaling factor for noise added to the sample.
+ generator (`torch.Generator`, *optional*):
+ A random number generator.
+ return_dict (`bool`):
+ Whether or not to return a [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] or
+ tuple.
+
+ Returns:
+ [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] or `tuple`:
+ If return_dict is `True`, [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] is
+ returned, otherwise a tuple is returned where the first element is the sample tensor.
+ """
+
+ if (
+ isinstance(timestep, int)
+ or isinstance(timestep, torch.IntTensor)
+ or isinstance(timestep, torch.LongTensor)
+ ):
+ raise ValueError(
+ (
+ "Passing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to"
+ " `EulerDiscreteScheduler.step()` is not supported. Make sure to pass"
+ " one of the `scheduler.timesteps` as a timestep."
+ ),
+ )
+
+ if self.step_index is None:
+ self._init_step_index(timestep)
+
+ # Upcast to avoid precision issues when computing prev_sample
+ sample = sample.to(torch.float32)
+
+ sigma = self.sigmas[self.step_index]
+ sigma_next = self.sigmas[self.step_index + 1]
+
+ prev_sample = sample + (sigma_next - sigma) * model_output
+
+ # Cast sample back to model compatible dtype
+ prev_sample = prev_sample.to(model_output.dtype)
+
+ # upon completion increase step index by one
+ self._step_index += 1
+
+ if not return_dict:
+ return (prev_sample,)
+
+ return FlowMatchEulerDiscreteSchedulerOutput(prev_sample=prev_sample)
+
+ def __len__(self):
+ return self.config.num_train_timesteps
+
+
+@dataclass
+class ConsistencyFlowMatchEulerDiscreteSchedulerOutput(BaseOutput):
+ prev_sample: torch.FloatTensor
+ pred_original_sample: torch.FloatTensor
+
+
+class ConsistencyFlowMatchEulerDiscreteScheduler(SchedulerMixin, ConfigMixin):
+ _compatibles = []
+ order = 1
+
+ @register_to_config
+ def __init__(
+ self,
+ num_train_timesteps: int = 1000,
+ pcm_timesteps: int = 50,
+ ):
+ sigmas = np.linspace(0, 1, num_train_timesteps)
+ step_ratio = num_train_timesteps // pcm_timesteps
+
+ euler_timesteps = (np.arange(1, pcm_timesteps) * step_ratio).round().astype(np.int64) - 1
+ euler_timesteps = np.asarray([0] + euler_timesteps.tolist())
+
+ self.euler_timesteps = euler_timesteps
+ self.sigmas = sigmas[self.euler_timesteps]
+ self.sigmas = torch.from_numpy((self.sigmas.copy())).to(dtype=torch.float32)
+ self.timesteps = self.sigmas * num_train_timesteps
+ self._step_index = None
+ self._begin_index = None
+ self.sigmas = self.sigmas.to("cpu") # to avoid too much CPU/GPU communication
+
+ @property
+ def step_index(self):
+ """
+ The index counter for current timestep. It will increase 1 after each scheduler step.
+ """
+ return self._step_index
+
+ @property
+ def begin_index(self):
+ """
+ The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
+ """
+ return self._begin_index
+
+ # Copied from diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler.set_begin_index
+ def set_begin_index(self, begin_index: int = 0):
+ """
+ Sets the begin index for the scheduler. This function should be run from pipeline before the inference.
+
+ Args:
+ begin_index (`int`):
+ The begin index for the scheduler.
+ """
+ self._begin_index = begin_index
+
+ def _sigma_to_t(self, sigma):
+ return sigma * self.config.num_train_timesteps
+
+ def set_timesteps(
+ self,
+ num_inference_steps: int = None,
+ device: Union[str, torch.device] = None,
+ sigmas: Optional[List[float]] = None,
+ ):
+ """
+ Sets the discrete timesteps used for the diffusion chain (to be run before inference).
+
+ Args:
+ num_inference_steps (`int`):
+ The number of diffusion steps used when generating samples with a pre-trained model.
+ device (`str` or `torch.device`, *optional*):
+ The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
+ """
+ self.num_inference_steps = num_inference_steps if num_inference_steps is not None else len(sigmas)
+ inference_indices = np.linspace(
+ 0, self.config.pcm_timesteps, num=self.num_inference_steps, endpoint=False
+ )
+ inference_indices = np.floor(inference_indices).astype(np.int64)
+ inference_indices = torch.from_numpy(inference_indices).long()
+
+ self.sigmas_ = self.sigmas[inference_indices]
+ timesteps = self.sigmas_ * self.config.num_train_timesteps
+ self.timesteps = timesteps.to(device=device)
+ self.sigmas_ = torch.cat(
+ [self.sigmas_, torch.ones(1, device=self.sigmas_.device)]
+ )
+
+ self._step_index = None
+ self._begin_index = None
+
+ def index_for_timestep(self, timestep, schedule_timesteps=None):
+ if schedule_timesteps is None:
+ schedule_timesteps = self.timesteps
+
+ indices = (schedule_timesteps == timestep).nonzero()
+
+ # The sigma index that is taken for the **very** first `step`
+ # is always the second index (or the last index if there is only 1)
+ # This way we can ensure we don't accidentally skip a sigma in
+ # case we start in the middle of the denoising schedule (e.g. for image-to-image)
+ pos = 1 if len(indices) > 1 else 0
+
+ return indices[pos].item()
+
+ def _init_step_index(self, timestep):
+ if self.begin_index is None:
+ if isinstance(timestep, torch.Tensor):
+ timestep = timestep.to(self.timesteps.device)
+ self._step_index = self.index_for_timestep(timestep)
+ else:
+ self._step_index = self._begin_index
+
+ def step(
+ self,
+ model_output: torch.FloatTensor,
+ timestep: Union[float, torch.FloatTensor],
+ sample: torch.FloatTensor,
+ generator: Optional[torch.Generator] = None,
+ return_dict: bool = True,
+ ) -> Union[ConsistencyFlowMatchEulerDiscreteSchedulerOutput, Tuple]:
+ if (
+ isinstance(timestep, int)
+ or isinstance(timestep, torch.IntTensor)
+ or isinstance(timestep, torch.LongTensor)
+ ):
+ raise ValueError(
+ (
+ "Passing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to"
+ " `EulerDiscreteScheduler.step()` is not supported. Make sure to pass"
+ " one of the `scheduler.timesteps` as a timestep."
+ ),
+ )
+
+ if self.step_index is None:
+ self._init_step_index(timestep)
+
+ sample = sample.to(torch.float32)
+
+ sigma = self.sigmas_[self.step_index]
+ sigma_next = self.sigmas_[self.step_index + 1]
+
+ prev_sample = sample + (sigma_next - sigma) * model_output
+ prev_sample = prev_sample.to(model_output.dtype)
+
+ pred_original_sample = sample + (1.0 - sigma) * model_output
+ pred_original_sample = pred_original_sample.to(model_output.dtype)
+
+ self._step_index += 1
+
+ if not return_dict:
+ return (prev_sample,)
+
+ return ConsistencyFlowMatchEulerDiscreteSchedulerOutput(prev_sample=prev_sample,
+ pred_original_sample=pred_original_sample)
+
+ def __len__(self):
+ return self.config.num_train_timesteps
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/surface_loaders.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/surface_loaders.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb638f367d4ca7a69078878aca5a36d5f60972dc
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/surface_loaders.py
@@ -0,0 +1,234 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+
+
+import numpy as np
+
+import torch
+import trimesh
+
+
+def normalize_mesh(mesh, scale=0.9999):
+ """
+ Normalize the mesh to fit inside a centered cube with a specified scale.
+
+ The mesh is translated so that its bounding box center is at the origin,
+ then uniformly scaled so that the longest side of the bounding box fits within [-scale, scale].
+
+ Args:
+ mesh (trimesh.Trimesh): Input mesh to normalize.
+ scale (float, optional): Scaling factor to slightly shrink the mesh inside the unit cube. Default is 0.9999.
+
+ Returns:
+ trimesh.Trimesh: The normalized mesh with applied translation and scaling.
+ """
+ bbox = mesh.bounds
+ center = (bbox[1] + bbox[0]) / 2
+ scale_ = (bbox[1] - bbox[0]).max()
+
+ mesh.apply_translation(-center)
+ mesh.apply_scale(1 / scale_ * 2 * scale)
+
+ return mesh
+
+
+def sample_pointcloud(mesh, num=200000):
+ """
+ Sample points uniformly from the surface of the mesh along with their corresponding face normals.
+
+ Args:
+ mesh (trimesh.Trimesh): Input mesh to sample from.
+ num (int, optional): Number of points to sample. Default is 200000.
+
+ Returns:
+ Tuple[torch.Tensor, torch.Tensor]:
+ - points: Sampled points as a float tensor of shape (num, 3).
+ - normals: Corresponding normals as a float tensor of shape (num, 3).
+ """
+ points, face_idx = mesh.sample(num, return_index=True)
+ normals = mesh.face_normals[face_idx]
+ points = torch.from_numpy(points.astype(np.float32))
+ normals = torch.from_numpy(normals.astype(np.float32))
+ return points, normals
+
+
+def load_surface(mesh, num_points=8192):
+ """
+ Normalize the mesh, sample points and normals from its surface, and randomly select a subset.
+
+ Args:
+ mesh (trimesh.Trimesh): Input mesh to process.
+ num_points (int, optional): Number of points to randomly select
+ from the sampled surface points. Default is 8192.
+
+ Returns:
+ Tuple[torch.Tensor, trimesh.Trimesh]:
+ - surface: Tensor of shape (1, num_points, 6), concatenating points and normals.
+ - mesh: The normalized mesh.
+ """
+
+ mesh = normalize_mesh(mesh, scale=0.98)
+ surface, normal = sample_pointcloud(mesh)
+
+ rng = np.random.default_rng(seed=0)
+ ind = rng.choice(surface.shape[0], num_points, replace=False)
+ surface = torch.FloatTensor(surface[ind])
+ normal = torch.FloatTensor(normal[ind])
+
+ surface = torch.cat([surface, normal], dim=-1).unsqueeze(0)
+
+ return surface, mesh
+
+
+def sharp_sample_pointcloud(mesh, num=16384):
+ """
+ Sample points and normals preferentially from sharp edges of the mesh.
+
+ Sharp edges are detected based on the angle between vertex normals and face normals.
+ Points are sampled along these edges proportionally to edge length.
+
+ Args:
+ mesh (trimesh.Trimesh): Input mesh to sample from.
+ num (int, optional): Number of points to sample from sharp edges. Default is 16384.
+
+ Returns:
+ Tuple[np.ndarray, np.ndarray]:
+ - samples: Sampled points along sharp edges, shape (num, 3).
+ - normals: Corresponding interpolated normals, shape (num, 3).
+ """
+ V = mesh.vertices
+ N = mesh.face_normals
+ VN = mesh.vertex_normals
+ F = mesh.faces
+ VN2 = np.ones(V.shape[0])
+ for i in range(3):
+ dot = np.stack((VN2[F[:, i]], np.sum(VN[F[:, i]] * N, axis=-1)), axis=-1)
+ VN2[F[:, i]] = np.min(dot, axis=-1)
+
+ sharp_mask = VN2 < 0.985
+ # collect edge
+ edge_a = np.concatenate((F[:, 0], F[:, 1], F[:, 2]))
+ edge_b = np.concatenate((F[:, 1], F[:, 2], F[:, 0]))
+ sharp_edge = ((sharp_mask[edge_a] * sharp_mask[edge_b]))
+ edge_a = edge_a[sharp_edge > 0]
+ edge_b = edge_b[sharp_edge > 0]
+
+ sharp_verts_a = V[edge_a]
+ sharp_verts_b = V[edge_b]
+ sharp_verts_an = VN[edge_a]
+ sharp_verts_bn = VN[edge_b]
+
+ weights = np.linalg.norm(sharp_verts_b - sharp_verts_a, axis=-1)
+ weights /= np.sum(weights)
+
+ random_number = np.random.rand(num)
+ w = np.random.rand(num, 1)
+ index = np.searchsorted(weights.cumsum(), random_number)
+ samples = w * sharp_verts_a[index] + (1 - w) * sharp_verts_b[index]
+ normals = w * sharp_verts_an[index] + (1 - w) * sharp_verts_bn[index]
+ return samples, normals
+
+
+def load_surface_sharpegde(mesh, num_points=4096, num_sharp_points=4096, sharpedge_flag=True):
+ try:
+ mesh_full = trimesh.util.concatenate(mesh.dump())
+ except Exception as err:
+ mesh_full = trimesh.util.concatenate(mesh)
+ mesh_full = normalize_mesh(mesh_full)
+
+ origin_num = mesh_full.faces.shape[0]
+ original_vertices = mesh_full.vertices
+ original_faces = mesh_full.faces
+
+ mesh = trimesh.Trimesh(vertices=original_vertices, faces=original_faces[:origin_num])
+ mesh_fill = trimesh.Trimesh(vertices=original_vertices, faces=original_faces[origin_num:])
+ area = mesh.area
+ area_fill = mesh_fill.area
+ sample_num = 499712 // 2
+ num_fill = int(sample_num * (area_fill / (area + area_fill)))
+ num = sample_num - num_fill
+
+ random_surface, random_normal = sample_pointcloud(mesh, num=num)
+ if num_fill == 0:
+ random_surface_fill, random_normal_fill = np.zeros((0, 3)), np.zeros((0, 3))
+ else:
+ random_surface_fill, random_normal_fill = sample_pointcloud(mesh_fill, num=num_fill)
+ random_sharp_surface, sharp_normal = sharp_sample_pointcloud(mesh, num=sample_num)
+
+ # save_surface
+ surface = np.concatenate((random_surface, random_normal), axis=1).astype(np.float16)
+ surface_fill = np.concatenate((random_surface_fill, random_normal_fill), axis=1).astype(np.float16)
+ sharp_surface = np.concatenate((random_sharp_surface, sharp_normal), axis=1).astype(np.float16)
+ surface = np.concatenate((surface, surface_fill), axis=0)
+ if sharpedge_flag:
+ sharpedge_label = np.zeros((surface.shape[0], 1))
+ surface = np.concatenate((surface, sharpedge_label), axis=1)
+ sharpedge_label = np.ones((sharp_surface.shape[0], 1))
+ sharp_surface = np.concatenate((sharp_surface, sharpedge_label), axis=1)
+ rng = np.random.default_rng()
+ ind = rng.choice(surface.shape[0], num_points, replace=False)
+ surface = torch.FloatTensor(surface[ind])
+ ind = rng.choice(sharp_surface.shape[0], num_sharp_points, replace=False)
+ sharp_surface = torch.FloatTensor(sharp_surface[ind])
+
+ return torch.cat([surface, sharp_surface], dim=0).unsqueeze(0), mesh_full
+
+
+class SurfaceLoader:
+ def __init__(self, num_points=8192):
+ self.num_points = num_points
+
+ def __call__(self, mesh_or_mesh_path, num_points=None):
+ if num_points is None:
+ num_points = self.num_points
+
+ mesh = mesh_or_mesh_path
+ if isinstance(mesh, str):
+ mesh = trimesh.load(mesh, force="mesh", merge_primitives=True)
+ if isinstance(mesh, trimesh.scene.Scene):
+ for idx, obj in enumerate(mesh.geometry.values()):
+ if idx == 0:
+ temp_mesh = obj
+ else:
+ temp_mesh = temp_mesh + obj
+ mesh = temp_mesh
+ surface, mesh = load_surface(mesh, num_points=num_points)
+ return surface
+
+
+class SharpEdgeSurfaceLoader:
+ def __init__(self, num_uniform_points=8192, num_sharp_points=8192, **kwargs):
+ self.num_uniform_points = num_uniform_points
+ self.num_sharp_points = num_sharp_points
+ self.num_points = num_uniform_points + num_sharp_points
+
+ def __call__(self, mesh_or_mesh_path, num_uniform_points=None, num_sharp_points=None):
+ if num_uniform_points is None:
+ num_uniform_points = self.num_uniform_points
+ if num_sharp_points is None:
+ num_sharp_points = self.num_sharp_points
+
+ mesh = mesh_or_mesh_path
+ if isinstance(mesh, str):
+ mesh = trimesh.load(mesh, force="mesh", merge_primitives=True)
+ if isinstance(mesh, trimesh.scene.Scene):
+ for idx, obj in enumerate(mesh.geometry.values()):
+ if idx == 0:
+ temp_mesh = obj
+ else:
+ temp_mesh = temp_mesh + obj
+ mesh = temp_mesh
+ surface, mesh = load_surface_sharpegde(mesh, num_points=num_uniform_points, num_sharp_points=num_sharp_points)
+ return surface
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/__init__.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..0f92daa391f814e1a2c2cad0601e10be49b71998
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+
+from .misc import get_config_from_file
+from .misc import instantiate_from_config
+from .utils import get_logger, logger, synchronize_timer, smart_load_model
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/ema.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/ema.py
new file mode 100644
index 0000000000000000000000000000000000000000..d90df922fd96ab831a2fa26cd16cf1b565fbeb2b
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/ema.py
@@ -0,0 +1,76 @@
+import torch
+from torch import nn
+
+
+class LitEma(nn.Module):
+ def __init__(self, model, decay=0.9999, use_num_updates=True):
+ super().__init__()
+ if decay < 0.0 or decay > 1.0:
+ raise ValueError('Decay must be between 0 and 1')
+
+ self.m_name2s_name = {}
+ self.register_buffer('decay', torch.tensor(decay, dtype=torch.float32))
+ self.register_buffer('num_updates', torch.tensor(0, dtype=torch.int) if use_num_updates
+ else torch.tensor(-1, dtype=torch.int))
+
+ for name, p in model.named_parameters():
+ if p.requires_grad:
+ # remove as '.'-character is not allowed in buffers
+ s_name = name.replace('.', '_____')
+ self.m_name2s_name.update({name: s_name})
+ self.register_buffer(s_name, p.clone().detach().data)
+
+ self.collected_params = []
+
+ def forward(self, model):
+ decay = self.decay
+
+ if self.num_updates >= 0:
+ self.num_updates += 1
+ decay = min(self.decay, (1 + self.num_updates) / (10 + self.num_updates))
+
+ one_minus_decay = 1.0 - decay
+
+ with torch.no_grad():
+ m_param = dict(model.named_parameters())
+ shadow_params = dict(self.named_buffers())
+
+ for key in m_param:
+ if m_param[key].requires_grad:
+ sname = self.m_name2s_name[key]
+ shadow_params[sname] = shadow_params[sname].type_as(m_param[key])
+ shadow_params[sname].sub_(one_minus_decay * (shadow_params[sname] - m_param[key]))
+ else:
+ assert not key in self.m_name2s_name
+
+ def copy_to(self, model):
+ m_param = dict(model.named_parameters())
+ shadow_params = dict(self.named_buffers())
+ for key in m_param:
+ if m_param[key].requires_grad:
+ m_param[key].data.copy_(shadow_params[self.m_name2s_name[key]].data)
+ else:
+ assert not key in self.m_name2s_name
+
+ def store(self, model):
+ """
+ Save the current parameters for restoring later.
+ Args:
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
+ temporarily stored.
+ """
+ self.collected_params = [param.clone() for param in model.parameters()]
+
+ def restore(self, model):
+ """
+ Restore the parameters stored with the `store` method.
+ Useful to validate the model with EMA parameters without affecting the
+ original optimization process. Store the parameters before the
+ `copy_to` method. After validation (or model saving), use this to
+ restore the former parameters.
+ Args:
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
+ updated with the stored parameters.
+ """
+ for c_param, param in zip(self.collected_params, model.parameters()):
+ param.data.copy_(c_param.data)
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/misc.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/misc.py
new file mode 100644
index 0000000000000000000000000000000000000000..55e11369611ccc60bb7b4afdd8b2d9efb14bf0d2
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/misc.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+
+import importlib
+from omegaconf import OmegaConf, DictConfig, ListConfig
+
+import torch
+import torch.distributed as dist
+from typing import Union
+
+
+def get_config_from_file(config_file: str) -> Union[DictConfig, ListConfig]:
+ config_file = OmegaConf.load(config_file)
+
+ if 'base_config' in config_file.keys():
+ if config_file['base_config'] == "default_base":
+ base_config = OmegaConf.create()
+ # base_config = get_default_config()
+ elif config_file['base_config'].endswith(".yaml"):
+ base_config = get_config_from_file(config_file['base_config'])
+ else:
+ raise ValueError(f"{config_file} must be `.yaml` file or it contains `base_config` key.")
+
+ config_file = {key: value for key, value in config_file if key != "base_config"}
+
+ return OmegaConf.merge(base_config, config_file)
+
+ return config_file
+
+
+def get_obj_from_str(string, reload=False):
+ module, cls = string.rsplit(".", 1)
+ if reload:
+ module_imp = importlib.import_module(module)
+ importlib.reload(module_imp)
+ return getattr(importlib.import_module(module, package=None), cls)
+
+
+def get_obj_from_config(config):
+ if "target" not in config:
+ raise KeyError("Expected key `target` to instantiate.")
+
+ return get_obj_from_str(config["target"])
+
+
+def instantiate_from_config(config, **kwargs):
+ if "target" not in config:
+ raise KeyError("Expected key `target` to instantiate.")
+
+ cls = get_obj_from_str(config["target"])
+
+ if config.get("from_pretrained", None):
+ return cls.from_pretrained(
+ config["from_pretrained"],
+ use_safetensors=config.get('use_safetensors', False),
+ variant=config.get('variant', 'fp16'))
+
+ params = config.get("params", dict())
+ # params.update(kwargs)
+ # instance = cls(**params)
+ kwargs.update(params)
+ instance = cls(**kwargs)
+
+ return instance
+
+
+def disabled_train(self, mode=True):
+ """Overwrite model.train with this function to make sure train/eval mode
+ does not change anymore."""
+ return self
+
+
+def instantiate_non_trainable_model(config):
+ model = instantiate_from_config(config)
+ model = model.eval()
+ model.train = disabled_train
+ for param in model.parameters():
+ param.requires_grad = False
+
+ return model
+
+
+def is_dist_avail_and_initialized():
+ if not dist.is_available():
+ return False
+ if not dist.is_initialized():
+ return False
+ return True
+
+
+def get_rank():
+ if not is_dist_avail_and_initialized():
+ return 0
+ return dist.get_rank()
+
+
+def get_world_size():
+ if not is_dist_avail_and_initialized():
+ return 1
+ return dist.get_world_size()
+
+
+def all_gather_batch(tensors):
+ """
+ Performs all_gather operation on the provided tensors.
+ """
+ # Queue the gathered tensors
+ world_size = get_world_size()
+ # There is no need for reduction in the single-proc case
+ if world_size == 1:
+ return tensors
+ tensor_list = []
+ output_tensor = []
+ for tensor in tensors:
+ tensor_all = [torch.ones_like(tensor) for _ in range(world_size)]
+ dist.all_gather(
+ tensor_all,
+ tensor,
+ async_op=False # performance opt
+ )
+
+ tensor_list.append(tensor_all)
+
+ for tensor_all in tensor_list:
+ output_tensor.append(torch.cat(tensor_all, dim=0))
+ return output_tensor
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/__init__.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/callback.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/callback.py
new file mode 100644
index 0000000000000000000000000000000000000000..e75ac9f99b89a397ae461a3df2f0c317c4216e06
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/callback.py
@@ -0,0 +1,213 @@
+# ------------------------------------------------------------------------------------
+# Modified from Taming Transformers (https://github.com/CompVis/taming-transformers)
+# Copyright (c) 2020 Patrick Esser and Robin Rombach and Björn Ommer. All Rights Reserved.
+# ------------------------------------------------------------------------------------
+
+import os
+import time
+import wandb
+import numpy as np
+from PIL import Image
+from pathlib import Path
+from omegaconf import OmegaConf, DictConfig
+from typing import Tuple, Generic, Dict, Callable, Optional, Any
+from pprint import pprint
+
+import torch
+import torchvision
+import pytorch_lightning as pl
+import pytorch_lightning.loggers
+from pytorch_lightning.loggers import WandbLogger
+from pytorch_lightning.loggers.logger import DummyLogger
+from pytorch_lightning.utilities import rank_zero_only, rank_zero_info
+from pytorch_lightning.callbacks import Callback
+
+from functools import wraps
+
+def node_zero_only(fn: Callable) -> Callable:
+ @wraps(fn)
+ def wrapped_fn(*args, **kwargs) -> Optional[Any]:
+ if node_zero_only.node == 0:
+ return fn(*args, **kwargs)
+ return None
+ return wrapped_fn
+
+node_zero_only.node = getattr(node_zero_only, 'node', int(os.environ.get('NODE_RANK', 0)))
+
+def node_zero_experiment(fn: Callable) -> Callable:
+ """Returns the real experiment on rank 0 and otherwise the DummyExperiment."""
+ @wraps(fn)
+ def experiment(self):
+ @node_zero_only
+ def get_experiment():
+ return fn(self)
+ return get_experiment() or DummyLogger.experiment
+ return experiment
+
+# customize wandb for node 0 only
+class MyWandbLogger(WandbLogger):
+ @WandbLogger.experiment.getter
+ @node_zero_experiment
+ def experiment(self):
+ return super().experiment
+
+class SetupCallback(Callback):
+ def __init__(self, config: DictConfig, exp_config: DictConfig,
+ basedir: Path, logdir: str = "log", ckptdir: str = "ckpt") -> None:
+ super().__init__()
+ self.logdir = basedir / logdir
+ self.ckptdir = basedir / ckptdir
+ self.config = config
+ self.exp_config = exp_config
+
+ # def on_pretrain_routine_start(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule) -> None:
+ # if trainer.global_rank == 0:
+ # # Create logdirs and save configs
+ # os.makedirs(self.logdir, exist_ok=True)
+ # os.makedirs(self.ckptdir, exist_ok=True)
+ #
+ # print("Experiment config")
+ # print(self.exp_config.pretty())
+ #
+ # print("Model config")
+ # print(self.config.pretty())
+
+ def on_fit_start(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule) -> None:
+ if trainer.global_rank == 0:
+ # Create logdirs and save configs
+ os.makedirs(self.logdir, exist_ok=True)
+ os.makedirs(self.ckptdir, exist_ok=True)
+
+ # print("Experiment config")
+ # pprint(self.exp_config)
+ #
+ # print("Model config")
+ # pprint(self.config)
+
+
+class ImageLogger(Callback):
+ def __init__(self, batch_frequency: int, max_images: int, clamp: bool = True,
+ increase_log_steps: bool = True) -> None:
+
+ super().__init__()
+ self.batch_freq = batch_frequency
+ self.max_images = max_images
+ self.logger_log_images = {
+ pl.loggers.WandbLogger: self._wandb,
+ pl.loggers.TestTubeLogger: self._testtube,
+ }
+ self.log_steps = [2 ** n for n in range(int(np.log2(self.batch_freq)) + 1)]
+ if not increase_log_steps:
+ self.log_steps = [self.batch_freq]
+ self.clamp = clamp
+
+ @rank_zero_only
+ def _wandb(self, pl_module, images, batch_idx, split):
+ # raise ValueError("No way wandb")
+ grids = dict()
+ for k in images:
+ grid = torchvision.utils.make_grid(images[k])
+ grids[f"{split}/{k}"] = wandb.Image(grid)
+ pl_module.logger.experiment.log(grids)
+
+ @rank_zero_only
+ def _testtube(self, pl_module, images, batch_idx, split):
+ for k in images:
+ grid = torchvision.utils.make_grid(images[k])
+ grid = (grid + 1.0) / 2.0 # -1,1 -> 0,1; c,h,w
+
+ tag = f"{split}/{k}"
+ pl_module.logger.experiment.add_image(
+ tag, grid,
+ global_step=pl_module.global_step)
+
+ @rank_zero_only
+ def log_local(self, save_dir: str, split: str, images: Dict,
+ global_step: int, current_epoch: int, batch_idx: int) -> None:
+ root = os.path.join(save_dir, "results", split)
+ os.makedirs(root, exist_ok=True)
+ for k in images:
+ grid = torchvision.utils.make_grid(images[k], nrow=4)
+
+ grid = grid.transpose(0, 1).transpose(1, 2).squeeze(-1)
+ grid = grid.numpy()
+ grid = (grid * 255).astype(np.uint8)
+ filename = "{}_gs-{:06}_e-{:06}_b-{:06}.png".format(
+ k,
+ global_step,
+ current_epoch,
+ batch_idx)
+ path = os.path.join(root, filename)
+ os.makedirs(os.path.split(path)[0], exist_ok=True)
+ Image.fromarray(grid).save(path)
+
+ def log_img(self, pl_module: pl.LightningModule, batch: Tuple[torch.LongTensor, torch.FloatTensor], batch_idx: int,
+ split: str = "train") -> None:
+ if (self.check_frequency(batch_idx) and # batch_idx % self.batch_freq == 0
+ hasattr(pl_module, "log_images") and
+ callable(pl_module.log_images) and
+ self.max_images > 0):
+ logger = type(pl_module.logger)
+
+ is_train = pl_module.training
+ if is_train:
+ pl_module.eval()
+
+ with torch.no_grad():
+ images = pl_module.log_images(batch, split=split, pl_module=pl_module)
+
+ for k in images:
+ N = min(images[k].shape[0], self.max_images)
+ images[k] = images[k][:N].detach().cpu()
+ if self.clamp:
+ images[k] = images[k].clamp(0, 1)
+
+ self.log_local(pl_module.logger.save_dir, split, images,
+ pl_module.global_step, pl_module.current_epoch, batch_idx)
+
+ logger_log_images = self.logger_log_images.get(logger, lambda *args, **kwargs: None)
+ logger_log_images(pl_module, images, pl_module.global_step, split)
+
+ if is_train:
+ pl_module.train()
+
+ def check_frequency(self, batch_idx: int) -> bool:
+ if (batch_idx % self.batch_freq) == 0 or (batch_idx in self.log_steps):
+ try:
+ self.log_steps.pop(0)
+ except IndexError:
+ pass
+ return True
+ return False
+
+ def on_train_batch_end(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule,
+ outputs: Generic, batch: Tuple[torch.LongTensor, torch.FloatTensor], batch_idx: int) -> None:
+ self.log_img(pl_module, batch, batch_idx, split="train")
+
+ def on_validation_batch_end(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule,
+ outputs: Generic, batch: Tuple[torch.LongTensor, torch.FloatTensor],
+ dataloader_idx: int, batch_idx: int) -> None:
+ self.log_img(pl_module, batch, batch_idx, split="val")
+
+
+class CUDACallback(Callback):
+ # see https://github.com/SeanNaren/minGPT/blob/master/mingpt/callback.py
+ def on_train_epoch_start(self, trainer, pl_module):
+ # Reset the memory use counter
+ torch.cuda.reset_peak_memory_stats(trainer.root_gpu)
+ torch.cuda.synchronize(trainer.root_gpu)
+ self.start_time = time.time()
+
+ def on_train_epoch_end(self, trainer, pl_module, outputs):
+ torch.cuda.synchronize(trainer.root_gpu)
+ max_memory = torch.cuda.max_memory_allocated(trainer.root_gpu) / 2 ** 20
+ epoch_time = time.time() - self.start_time
+
+ try:
+ max_memory = trainer.training_type_plugin.reduce(max_memory)
+ epoch_time = trainer.training_type_plugin.reduce(epoch_time)
+
+ rank_zero_info(f"Average Epoch time: {epoch_time:.2f} seconds")
+ rank_zero_info(f"Average Peak memory {max_memory:.2f}MiB")
+ except AttributeError:
+ pass
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/lr_scheduler.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/lr_scheduler.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb7224776457a4395d309628ab62360d85cec1dc
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/lr_scheduler.py
@@ -0,0 +1,53 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import numpy as np
+
+
+class BaseScheduler(object):
+
+ def schedule(self, n, **kwargs):
+ raise NotImplementedError
+
+
+class LambdaWarmUpCosineFactorScheduler(BaseScheduler):
+ """
+ note: use with a base_lr of 1.0
+ """
+ def __init__(self, warm_up_steps, f_min, f_max, f_start, max_decay_steps, verbosity_interval=0, **ignore_kwargs):
+ self.lr_warm_up_steps = warm_up_steps
+ self.f_start = f_start
+ self.f_min = f_min
+ self.f_max = f_max
+ self.lr_max_decay_steps = max_decay_steps
+ self.last_f = 0.
+ self.verbosity_interval = verbosity_interval
+
+ def schedule(self, n, **kwargs):
+ if self.verbosity_interval > 0:
+ if n % self.verbosity_interval == 0:
+ print(f"current step: {n}, recent lr-multiplier: {self.f_start}")
+ if n < self.lr_warm_up_steps:
+ f = (self.f_max - self.f_start) / self.lr_warm_up_steps * n + self.f_start
+ self.last_f = f
+ return f
+ else:
+ t = (n - self.lr_warm_up_steps) / (self.lr_max_decay_steps - self.lr_warm_up_steps)
+ t = min(t, 1.0)
+ f = self.f_min + 0.5 * (self.f_max - self.f_min) * (1 + np.cos(t * np.pi))
+ self.last_f = f
+ return f
+
+ def __call__(self, n, **kwargs):
+ return self.schedule(n, **kwargs)
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh.py
new file mode 100644
index 0000000000000000000000000000000000000000..0af7da6256ecde08c49e7a2bc88d0a22e8e67fc7
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+import cv2
+import numpy as np
+import PIL.Image
+from typing import Optional
+
+import trimesh
+
+
+def save_obj(pointnp_px3, facenp_fx3, fname):
+ fid = open(fname, "w")
+ write_str = ""
+ for pidx, p in enumerate(pointnp_px3):
+ pp = p
+ write_str += "v %f %f %f\n" % (pp[0], pp[1], pp[2])
+
+ for i, f in enumerate(facenp_fx3):
+ f1 = f + 1
+ write_str += "f %d %d %d\n" % (f1[0], f1[1], f1[2])
+ fid.write(write_str)
+ fid.close()
+ return
+
+
+def savemeshtes2(pointnp_px3, tcoords_px2, facenp_fx3, facetex_fx3, tex_map, fname):
+ fol, na = os.path.split(fname)
+ na, _ = os.path.splitext(na)
+
+ matname = "%s/%s.mtl" % (fol, na)
+ fid = open(matname, "w")
+ fid.write("newmtl material_0\n")
+ fid.write("Kd 1 1 1\n")
+ fid.write("Ka 0 0 0\n")
+ fid.write("Ks 0.4 0.4 0.4\n")
+ fid.write("Ns 10\n")
+ fid.write("illum 2\n")
+ fid.write("map_Kd %s.png\n" % na)
+ fid.close()
+ ####
+
+ fid = open(fname, "w")
+ fid.write("mtllib %s.mtl\n" % na)
+
+ for pidx, p3 in enumerate(pointnp_px3):
+ pp = p3
+ fid.write("v %f %f %f\n" % (pp[0], pp[1], pp[2]))
+
+ for pidx, p2 in enumerate(tcoords_px2):
+ pp = p2
+ fid.write("vt %f %f\n" % (pp[0], pp[1]))
+
+ fid.write("usemtl material_0\n")
+ for i, f in enumerate(facenp_fx3):
+ f1 = f + 1
+ f2 = facetex_fx3[i] + 1
+ fid.write("f %d/%d %d/%d %d/%d\n" % (f1[0], f2[0], f1[1], f2[1], f1[2], f2[2]))
+ fid.close()
+
+ PIL.Image.fromarray(np.ascontiguousarray(tex_map), "RGB").save(
+ os.path.join(fol, "%s.png" % na))
+
+ return
+
+
+class MeshOutput(object):
+
+ def __init__(self,
+ mesh_v: np.ndarray,
+ mesh_f: np.ndarray,
+ vertex_colors: Optional[np.ndarray] = None,
+ uvs: Optional[np.ndarray] = None,
+ mesh_tex_idx: Optional[np.ndarray] = None,
+ tex_map: Optional[np.ndarray] = None):
+
+ self.mesh_v = mesh_v
+ self.mesh_f = mesh_f
+ self.vertex_colors = vertex_colors
+ self.uvs = uvs
+ self.mesh_tex_idx = mesh_tex_idx
+ self.tex_map = tex_map
+
+ def contain_uv_texture(self):
+ return (self.uvs is not None) and (self.mesh_tex_idx is not None) and (self.tex_map is not None)
+
+ def contain_vertex_colors(self):
+ return self.vertex_colors is not None
+
+ def export(self, fname):
+
+ if self.contain_uv_texture():
+ savemeshtes2(
+ self.mesh_v,
+ self.uvs,
+ self.mesh_f,
+ self.mesh_tex_idx,
+ self.tex_map,
+ fname
+ )
+
+ elif self.contain_vertex_colors():
+ mesh_obj = trimesh.Trimesh(vertices=self.mesh_v, faces=self.mesh_f, vertex_colors=self.vertex_colors)
+ mesh_obj.export(fname)
+
+ else:
+ save_obj(
+ self.mesh_v,
+ self.mesh_f,
+ fname
+ )
+
+
+
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh_log_callback.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh_log_callback.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2466d581d75d4fbe923cdf91cbb8ddb919af456
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/mesh_log_callback.py
@@ -0,0 +1,336 @@
+# -*- coding: utf-8 -*-
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import json
+import math
+import os
+from typing import Tuple, Generic, Dict, List, Union, Optional
+
+import trimesh
+import numpy as np
+import pytorch_lightning as pl
+import pytorch_lightning.loggers
+import torch
+import torchvision
+from pytorch_lightning.callbacks import Callback
+from pytorch_lightning.utilities import rank_zero_only
+
+from hy3dshape.pipelines import export_to_trimesh
+from hy3dshape.utils.trainings.mesh import MeshOutput
+from hy3dshape.utils.visualizers import html_util
+from hy3dshape.utils.visualizers.pythreejs_viewer import PyThreeJSViewer
+
+
+class ImageConditionalASLDiffuserLogger(Callback):
+ def __init__(self,
+ step_frequency: int,
+ num_samples: int = 1,
+ mean: Optional[Union[List[float], Tuple[float]]] = None,
+ std: Optional[Union[List[float], Tuple[float]]] = None,
+ bounds: Union[List[float], Tuple[float]] = (-1.1, -1.1, -1.1, 1.1, 1.1, 1.1),
+ **kwargs) -> None:
+
+ super().__init__()
+ self.bbox_size = np.array(bounds[3:6]) - np.array(bounds[0:3])
+
+ if mean is not None:
+ mean = np.asarray(mean)
+
+ if std is not None:
+ std = np.asarray(std)
+
+ self.mean = mean
+ self.std = std
+
+ self.step_freq = step_frequency
+ self.num_samples = num_samples
+ self.has_train_logged = False
+ self.logger_log_images = {
+ pl.loggers.WandbLogger: self._wandb,
+ }
+
+ self.viewer = PyThreeJSViewer(settings={}, render_mode="WEBSITE")
+
+ @rank_zero_only
+ def _wandb(self, pl_module, images, batch_idx, split):
+ # raise ValueError("No way wandb")
+ grids = dict()
+ for k in images:
+ grid = torchvision.utils.make_grid(images[k])
+ grids[f"{split}/{k}"] = wandb.Image(grid)
+ pl_module.logger.experiment.log(grids)
+
+ def log_local(self,
+ outputs: List[List['Latent2MeshOutput']],
+ images: Union[np.ndarray, List[np.ndarray]],
+ description: List[str],
+ keys: List[str],
+ save_dir: str, split: str,
+ global_step: int, current_epoch: int, batch_idx: int,
+ prog_bar: bool = False,
+ multi_views=None, # yf ...
+ ) -> None:
+
+ folder = "gs-{:010}_e-{:06}_b-{:06}".format(global_step, current_epoch, batch_idx)
+ visual_dir = os.path.join(save_dir, "visuals", split, folder)
+ os.makedirs(visual_dir, exist_ok=True)
+
+ num_samples = len(images)
+
+ for i in range(num_samples):
+ key_i = keys[i]
+ image_i = self.denormalize_image(images[i])
+ shape_tag_i = description[i]
+
+ for j in range(1):
+ mesh = outputs[j][i]
+ if mesh is None:
+ continue
+
+ mesh_v = mesh.mesh_v.copy()
+ mesh_v[:, 0] += j * np.max(self.bbox_size)
+ self.viewer.add_mesh(mesh_v, mesh.mesh_f)
+
+ image_tag = html_util.to_image_embed_tag(image_i)
+ mesh_tag = self.viewer.to_html(html_frame=False)
+
+ table_tag = f"""
+
+ {shape_tag_i} - {key_i}
+ Input Image | Generated Mesh
+
+ {image_tag}
+ {mesh_tag}
+
+
+ """
+
+ if multi_views is not None:
+ multi_views_i = self.make_grid(multi_views[i])
+ views_tag = html_util.to_image_embed_tag(self.denormalize_image(multi_views_i))
+ table_tag = f"""
+
+ {shape_tag_i} - {key_i}
+ Input Image | Generated Mesh
+
+ {image_tag}
+ {views_tag}
+ {mesh_tag}
+
+
+ """
+
+ html_frame = html_util.to_html_frame(table_tag)
+ if len(key_i) > 100:
+ key_i = key_i[:100]
+ with open(os.path.join(visual_dir, f"{key_i}.html"), "w") as writer:
+ writer.write(html_frame)
+
+ self.viewer.reset()
+
+ def log_sample(self,
+ pl_module: pl.LightningModule,
+ batch: Dict[str, torch.FloatTensor],
+ batch_idx: int,
+ split: str = "train") -> None:
+ """
+
+ Args:
+ pl_module:
+ batch (dict): the batch sample information, and it contains:
+ - surface (torch.FloatTensor):
+ - image (torch.FloatTensor):
+ batch_idx (int):
+ split (str):
+
+ Returns:
+
+ """
+
+ is_train = pl_module.training
+ if is_train:
+ pl_module.eval()
+
+ batch_size = len(batch["surface"])
+ replace = batch_size < self.num_samples
+ ids = np.random.choice(batch_size, self.num_samples, replace=replace)
+
+ with torch.no_grad():
+ # run text to mesh
+ # keys = [batch["__key__"][i] for i in ids]
+ keys = [f'key_{i}' for i in ids]
+ # texts = [batch["text"][i] for i in ids]
+ texts = [f'text_{i}'for i in ids]
+ # description = [batch["description"][i] for i in ids]
+ description = [f'desc_{i}' for i in ids]
+ images = batch["image"][ids]
+ mask_input = batch["mask"][ids] if 'mask' in batch else None
+ sample_batch = {
+ "__key__": keys,
+ "image": images,
+ 'text': texts,
+ 'mask': mask_input,
+ }
+
+ # if 'cam_parm' in batch:
+ # sample_batch['cam_parm'] = batch['cam_parm'][ids]
+
+ # if 'multi_views' in batch: # yf ...
+ # sample_batch['multi_views'] = batch['multi_views'][ids]
+
+ outputs = pl_module.sample(
+ batch=sample_batch,
+ output_type='latents2mesh'
+ )
+
+ images = images.cpu().float().numpy()
+ # images = self.denormalize_image(images)
+ # images = np.transpose(images, (0, 2, 3, 1))
+ # images = ((images + 1) / 2 * 255).astype(np.uint8)
+
+ self.log_local(outputs, images, description, keys, pl_module.logger.save_dir, split,
+ pl_module.global_step, pl_module.current_epoch, batch_idx, prog_bar=False,
+ multi_views=sample_batch.get('multi_views'))
+
+ if is_train: pl_module.train()
+
+ def make_grid(self, images): # return (3,h,w) in (0,1) ...
+ images_resized = []
+ for img in images:
+ img_resized = torchvision.transforms.functional.resize(img, (320, 320))
+ images_resized.append(img_resized)
+ image = torchvision.utils.make_grid(images_resized, nrow=2, padding=5, pad_value=255)
+
+ image = image.cpu().numpy()
+ # image = np.transpose(image, (1, 2, 0))
+ # image = (image * 255).astype(np.uint8)
+
+ return image
+
+ def check_frequency(self, step: int) -> bool:
+ if step % self.step_freq == 0:
+ return True
+ return False
+
+ def on_train_batch_end(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule,
+ outputs: Generic, batch: Dict[str, torch.FloatTensor], batch_idx: int) -> None:
+
+ if (self.check_frequency(pl_module.global_step) and # batch_idx % self.batch_freq == 0
+ hasattr(pl_module, "sample") and
+ callable(pl_module.sample) and
+ self.num_samples > 0):
+ self.log_sample(pl_module, batch, batch_idx, split="train")
+ self.has_train_logged = True
+
+ def on_validation_batch_end(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule,
+ outputs: Generic, batch: Dict[str, torch.FloatTensor],
+ dataloader_idx: int, batch_idx: int) -> None:
+
+ if self.has_train_logged:
+ self.log_sample(pl_module, batch, batch_idx, split="val")
+ self.has_train_logged = False
+
+ def denormalize_image(self, image):
+ """
+
+ Args:
+ image (np.ndarray): [3, h, w]
+
+ Returns:
+ image (np.ndarray): [h, w, 3], np.uint8, [0, 255].
+ """
+ # image = np.transpose(image, (0, 2, 3, 1))
+ image = np.transpose(image, (1, 2, 0))
+
+ if self.std is not None:
+ image = image * self.std
+
+ if self.mean is not None:
+ image = image + self.mean
+
+ image = (image * 255).astype(np.uint8)
+
+ return image
+
+
+class ImageConditionalFixASLDiffuserLogger(Callback):
+ def __init__(
+ self,
+ step_frequency: int,
+ test_data_path: str,
+ max_size: int = None,
+ save_dir: str = 'infer',
+ **kwargs,
+ ) -> None:
+ super().__init__()
+ self.step_freq = step_frequency
+ self.viewer = PyThreeJSViewer(settings={}, render_mode="WEBSITE")
+
+ self.test_data_path = test_data_path
+ with open(self.test_data_path, 'r') as f:
+ data = json.load(f)
+ self.file_list = data['file_list']
+ self.file_folder = data['file_folder']
+ if max_size is not None:
+ self.file_list = self.file_list[:max_size]
+ self.kwargs = kwargs
+ self.save_dir = save_dir
+
+ def on_train_batch_end(
+ self,
+ trainer: pl.trainer.Trainer,
+ pl_module: pl.LightningModule,
+ outputs: Generic,
+ batch: Dict[str, torch.FloatTensor],
+ batch_idx: int,
+ ):
+ if pl_module.global_step % self.step_freq == 0:
+ is_train = pl_module.training
+ if is_train:
+ pl_module.eval()
+
+ folder_path = self.file_folder
+ folder_name = os.path.basename(folder_path)
+ folder = "gs-{:010}_e-{:06}_b-{:06}".format(pl_module.global_step, pl_module.current_epoch, batch_idx)
+ visual_dir = os.path.join(pl_module.logger.save_dir, self.save_dir, folder, folder_name)
+ os.makedirs(visual_dir, exist_ok=True)
+
+ image_paths = self.file_list
+ chunk_size = math.ceil(len(image_paths) / trainer.world_size)
+ if pl_module.global_rank == trainer.world_size - 1:
+ image_paths = image_paths[pl_module.global_rank * chunk_size:]
+ else:
+ image_paths = image_paths[pl_module.global_rank * chunk_size:(pl_module.global_rank + 1) * chunk_size]
+
+ print(f'Rank{pl_module.global_rank}: processing {len(image_paths)}|{len(self.file_list)} images')
+ for image_path in image_paths:
+ if folder_path in image_path:
+ save_path = image_path.replace(folder_path, visual_dir)
+ else:
+ save_path = os.path.join(visual_dir, os.path.basename(image_path))
+ save_path = os.path.splitext(save_path)[0] + '.glb'
+
+ print(image_path)
+ with torch.no_grad():
+ mesh = pl_module.sample(batch={"image": image_path}, **self.kwargs)[0][0]
+ if isinstance(mesh, tuple) and len(mesh)==2:
+ mesh = export_to_trimesh(mesh)
+ elif isinstance(mesh, trimesh.Trimesh):
+ os.makedirs(os.path.dirname(save_path), exist_ok=True)
+ mesh.export(save_path)
+
+ if is_train:
+ pl_module.train()
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/peft.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/peft.py
new file mode 100644
index 0000000000000000000000000000000000000000..7b999defbb3b74a63ea86f9d6bf8e7851ff760b9
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/trainings/peft.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import os
+from pytorch_lightning.callbacks import Callback
+from omegaconf import OmegaConf, ListConfig
+
+class PeftSaveCallback(Callback):
+ def __init__(self, peft_model, save_dir: str, save_every_n_steps: int = None):
+ super().__init__()
+ self.peft_model = peft_model
+ self.save_dir = save_dir
+ self.save_every_n_steps = save_every_n_steps
+ os.makedirs(self.save_dir, exist_ok=True)
+
+ def recursive_convert(self, obj):
+ from omegaconf import OmegaConf, ListConfig
+ if isinstance(obj, (OmegaConf, ListConfig)):
+ return OmegaConf.to_container(obj, resolve=True)
+ elif isinstance(obj, dict):
+ return {k: self.recursive_convert(v) for k, v in obj.items()}
+ elif isinstance(obj, list):
+ return [self.recursive_convert(i) for i in obj]
+ elif isinstance(obj, type):
+ # 避免修改类对象
+ return obj
+ elif hasattr(obj, '__dict__'):
+ for attr_name, attr_value in vars(obj).items():
+ setattr(obj, attr_name, self.recursive_convert(attr_value))
+ return obj
+ else:
+ return obj
+
+ # def recursive_convert(self, obj):
+ # if isinstance(obj, (OmegaConf, ListConfig)):
+ # return OmegaConf.to_container(obj, resolve=True)
+ # elif isinstance(obj, dict):
+ # return {k: self.recursive_convert(v) for k, v in obj.items()}
+ # elif isinstance(obj, list):
+ # return [self.recursive_convert(i) for i in obj]
+ # elif hasattr(obj, '__dict__'):
+ # for attr_name, attr_value in vars(obj).items():
+ # setattr(obj, attr_name, self.recursive_convert(attr_value))
+ # return obj
+ # else:
+ # return obj
+
+ def _convert_peft_config(self):
+ pc = self.peft_model.peft_config
+ self.peft_model.peft_config = self.recursive_convert(pc)
+
+ def on_train_epoch_end(self, trainer, pl_module):
+ self._convert_peft_config()
+ save_path = os.path.join(self.save_dir, f"epoch_{trainer.current_epoch}")
+ self.peft_model.save_pretrained(save_path)
+ print(f"[PeftSaveCallback] Saved LoRA weights to {save_path}")
+
+ def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch_idx):
+ if self.save_every_n_steps is not None:
+ global_step = trainer.global_step
+ if global_step % self.save_every_n_steps == 0 and global_step > 0:
+ self._convert_peft_config()
+ save_path = os.path.join(self.save_dir, f"step_{global_step}")
+ self.peft_model.save_pretrained(save_path)
+ print(f"[PeftSaveCallback] Saved LoRA weights to {save_path}")
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/utils.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..c88f6bb9a9e3f7aaf0ce68753757cd7816489915
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/utils.py
@@ -0,0 +1,128 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import logging
+import os
+from functools import wraps
+
+import torch
+
+
+def get_logger(name):
+ logger = logging.getLogger(name)
+ logger.setLevel(logging.INFO)
+
+ console_handler = logging.StreamHandler()
+ console_handler.setLevel(logging.INFO)
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ console_handler.setFormatter(formatter)
+ logger.addHandler(console_handler)
+ return logger
+
+
+logger = get_logger('hy3dgen.shapgen')
+
+
+class synchronize_timer:
+ """ Synchronized timer to count the inference time of `nn.Module.forward`.
+
+ Supports both context manager and decorator usage.
+
+ Example as context manager:
+ ```python
+ with synchronize_timer('name') as t:
+ run()
+ ```
+
+ Example as decorator:
+ ```python
+ @synchronize_timer('Export to trimesh')
+ def export_to_trimesh(mesh_output):
+ pass
+ ```
+ """
+
+ def __init__(self, name=None):
+ self.name = name
+
+ def __enter__(self):
+ """Context manager entry: start timing."""
+ if os.environ.get('HY3DGEN_DEBUG', '0') == '1':
+ self.start = torch.cuda.Event(enable_timing=True)
+ self.end = torch.cuda.Event(enable_timing=True)
+ self.start.record()
+ return lambda: self.time
+
+ def __exit__(self, exc_type, exc_value, exc_tb):
+ """Context manager exit: stop timing and log results."""
+ if os.environ.get('HY3DGEN_DEBUG', '0') == '1':
+ self.end.record()
+ torch.cuda.synchronize()
+ self.time = self.start.elapsed_time(self.end)
+ if self.name is not None:
+ logger.info(f'{self.name} takes {self.time} ms')
+
+ def __call__(self, func):
+ """Decorator: wrap the function to time its execution."""
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ with self:
+ result = func(*args, **kwargs)
+ return result
+
+ return wrapper
+
+
+def smart_load_model(
+ model_path,
+ subfolder,
+ use_safetensors,
+ variant,
+):
+ original_model_path = model_path
+ # try local path
+ base_dir = os.environ.get('HY3DGEN_MODELS', '~/.cache/hy3dgen')
+ model_fld = os.path.expanduser(os.path.join(base_dir, model_path))
+ model_path = os.path.expanduser(os.path.join(base_dir, model_path, subfolder))
+ logger.info(f'Try to load model from local path: {model_path}')
+ if not os.path.exists(model_path):
+ logger.info('Model path not exists, try to download from huggingface')
+ try:
+ from huggingface_hub import snapshot_download
+ # 只下载指定子目录
+ path = snapshot_download(
+ repo_id=original_model_path,
+ allow_patterns=[f"{subfolder}/*"], # 关键修改:模式匹配子文件夹
+ local_dir=model_fld
+ )
+ model_path = os.path.join(path, subfolder) # 保持路径拼接逻辑不变
+ except ImportError:
+ logger.warning(
+ "You need to install HuggingFace Hub to load models from the hub."
+ )
+ raise RuntimeError(f"Model path {model_path} not found")
+ except Exception as e:
+ raise e
+
+ if not os.path.exists(model_path):
+ raise FileNotFoundError(f"Model path {original_model_path} not found")
+
+ extension = 'ckpt' if not use_safetensors else 'safetensors'
+ variant = '' if variant is None else f'.{variant}'
+ ckpt_name = f'model{variant}.{extension}'
+ config_path = os.path.join(model_path, 'config.yaml')
+ ckpt_path = os.path.join(model_path, ckpt_name)
+ return config_path, ckpt_path
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/__init__.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/color_util.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/color_util.py
new file mode 100644
index 0000000000000000000000000000000000000000..64f5ed382d657bcab3420c57f12845ba74bc9df7
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/color_util.py
@@ -0,0 +1,57 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import numpy as np
+import matplotlib.pyplot as plt
+
+
+# Helper functions
+def get_colors(inp, colormap="viridis", normalize=True, vmin=None, vmax=None):
+ colormap = plt.cm.get_cmap(colormap)
+ if normalize:
+ vmin = np.min(inp)
+ vmax = np.max(inp)
+
+ norm = plt.Normalize(vmin, vmax)
+ return colormap(norm(inp))[:, :3]
+
+
+def gen_checkers(n_checkers_x, n_checkers_y, width=256, height=256):
+ # tex dims need to be power of two.
+ array = np.ones((width, height, 3), dtype='float32')
+
+ # width in texels of each checker
+ checker_w = width / n_checkers_x
+ checker_h = height / n_checkers_y
+
+ for y in range(height):
+ for x in range(width):
+ color_key = int(x / checker_w) + int(y / checker_h)
+ if color_key % 2 == 0:
+ array[x, y, :] = [1., 0.874, 0.0]
+ else:
+ array[x, y, :] = [0., 0., 0.]
+ return array
+
+
+def gen_circle(width=256, height=256):
+ xx, yy = np.mgrid[:width, :height]
+ circle = (xx - width / 2 + 0.5) ** 2 + (yy - height / 2 + 0.5) ** 2
+ array = np.ones((width, height, 4), dtype='float32')
+ array[:, :, 0] = (circle <= width)
+ array[:, :, 1] = (circle <= width)
+ array[:, :, 2] = (circle <= width)
+ array[:, :, 3] = circle <= width
+ return array
+
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/html_util.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/html_util.py
new file mode 100644
index 0000000000000000000000000000000000000000..b31c403777e44b948a088e6a60331061525e7a80
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/html_util.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import io
+import base64
+import numpy as np
+from PIL import Image
+
+
+def to_html_frame(content):
+
+ html_frame = f"""
+
+
+ {content}
+
+
+ """
+
+ return html_frame
+
+
+def to_single_row_table(caption: str, content: str):
+
+ table_html = f"""
+
+ {caption}
+
+ {content}
+
+
+ """
+
+ return table_html
+
+
+def to_image_embed_tag(image: np.ndarray):
+
+ # Convert np.ndarray to bytes
+ img = Image.fromarray(image)
+ raw_bytes = io.BytesIO()
+ img.save(raw_bytes, "PNG")
+
+ # Encode bytes to base64
+ image_base64 = base64.b64encode(raw_bytes.getvalue()).decode("utf-8")
+
+ image_tag = f"""
+
+ """
+
+ return image_tag
diff --git a/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/pythreejs_viewer.py b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/pythreejs_viewer.py
new file mode 100644
index 0000000000000000000000000000000000000000..817d2efaf74f376a419eae893996540fa643a38d
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/hy3dshape/utils/visualizers/pythreejs_viewer.py
@@ -0,0 +1,549 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+
+import numpy as np
+from ipywidgets import embed
+import pythreejs as p3s
+import uuid
+
+from .color_util import get_colors, gen_circle, gen_checkers
+
+
+EMBED_URL = "https://cdn.jsdelivr.net/npm/@jupyter-widgets/html-manager@1.0.1/dist/embed-amd.js"
+
+
+class PyThreeJSViewer(object):
+
+ def __init__(self, settings, render_mode="WEBSITE"):
+ self.render_mode = render_mode
+ self.__update_settings(settings)
+ self._light = p3s.DirectionalLight(color='white', position=[0, 0, 1], intensity=0.6)
+ self._light2 = p3s.AmbientLight(intensity=0.5)
+ self._cam = p3s.PerspectiveCamera(position=[0, 0, 1], lookAt=[0, 0, 0], fov=self.__s["fov"],
+ aspect=self.__s["width"] / self.__s["height"], children=[self._light])
+ self._orbit = p3s.OrbitControls(controlling=self._cam)
+ self._scene = p3s.Scene(children=[self._cam, self._light2], background=self.__s["background"]) # "#4c4c80"
+ self._renderer = p3s.Renderer(camera=self._cam, scene=self._scene, controls=[self._orbit],
+ width=self.__s["width"], height=self.__s["height"],
+ antialias=self.__s["antialias"])
+
+ self.__objects = {}
+ self.__cnt = 0
+
+ def jupyter_mode(self):
+ self.render_mode = "JUPYTER"
+
+ def offline(self):
+ self.render_mode = "OFFLINE"
+
+ def website(self):
+ self.render_mode = "WEBSITE"
+
+ def __get_shading(self, shading):
+ shad = {"flat": True, "wireframe": False, "wire_width": 0.03, "wire_color": "black",
+ "side": 'DoubleSide', "colormap": "viridis", "normalize": [None, None],
+ "bbox": False, "roughness": 0.5, "metalness": 0.25, "reflectivity": 1.0,
+ "line_width": 1.0, "line_color": "black",
+ "point_color": "red", "point_size": 0.01, "point_shape": "circle",
+ "text_color": "red"
+ }
+ for k in shading:
+ shad[k] = shading[k]
+ return shad
+
+ def __update_settings(self, settings={}):
+ sett = {"width": 1600, "height": 800, "antialias": True, "scale": 1.5, "background": "#ffffff",
+ "fov": 30}
+ for k in settings:
+ sett[k] = settings[k]
+ self.__s = sett
+
+ def __add_object(self, obj, parent=None):
+ if not parent: # Object is added to global scene and objects dict
+ self.__objects[self.__cnt] = obj
+ self.__cnt += 1
+ self._scene.add(obj["mesh"])
+ else: # Object is added to parent object and NOT to objects dict
+ parent.add(obj["mesh"])
+
+ self.__update_view()
+
+ if self.render_mode == "JUPYTER":
+ return self.__cnt - 1
+ elif self.render_mode == "WEBSITE":
+ return self
+
+ def __add_line_geometry(self, lines, shading, obj=None):
+ lines = lines.astype("float32", copy=False)
+ mi = np.min(lines, axis=0)
+ ma = np.max(lines, axis=0)
+
+ geometry = p3s.LineSegmentsGeometry(positions=lines.reshape((-1, 2, 3)))
+ material = p3s.LineMaterial(linewidth=shading["line_width"], color=shading["line_color"])
+ # , vertexColors='VertexColors'),
+ lines = p3s.LineSegments2(geometry=geometry, material=material) # type='LinePieces')
+ line_obj = {"geometry": geometry, "mesh": lines, "material": material,
+ "max": ma, "min": mi, "type": "Lines", "wireframe": None}
+
+ if obj:
+ return self.__add_object(line_obj, obj), line_obj
+ else:
+ return self.__add_object(line_obj)
+
+ def __update_view(self):
+ if len(self.__objects) == 0:
+ return
+ ma = np.zeros((len(self.__objects), 3))
+ mi = np.zeros((len(self.__objects), 3))
+ for r, obj in enumerate(self.__objects):
+ ma[r] = self.__objects[obj]["max"]
+ mi[r] = self.__objects[obj]["min"]
+ ma = np.max(ma, axis=0)
+ mi = np.min(mi, axis=0)
+ diag = np.linalg.norm(ma - mi)
+ mean = ((ma - mi) / 2 + mi).tolist()
+ scale = self.__s["scale"] * (diag)
+ self._orbit.target = mean
+ self._cam.lookAt(mean)
+ self._cam.position = [mean[0], mean[1], mean[2] + scale]
+ self._light.position = [mean[0], mean[1], mean[2] + scale]
+
+ self._orbit.exec_three_obj_method('update')
+ self._cam.exec_three_obj_method('updateProjectionMatrix')
+
+ def __get_bbox(self, v):
+ m = np.min(v, axis=0)
+ M = np.max(v, axis=0)
+
+ # Corners of the bounding box
+ v_box = np.array([[m[0], m[1], m[2]], [M[0], m[1], m[2]], [M[0], M[1], m[2]], [m[0], M[1], m[2]],
+ [m[0], m[1], M[2]], [M[0], m[1], M[2]], [M[0], M[1], M[2]], [m[0], M[1], M[2]]])
+
+ f_box = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4],
+ [0, 4], [1, 5], [2, 6], [7, 3]], dtype=np.uint32)
+ return v_box, f_box
+
+ def __get_colors(self, v, f, c, sh):
+ coloring = "VertexColors"
+ if type(c) == np.ndarray and c.size == 3: # Single color
+ colors = np.ones_like(v)
+ colors[:, 0] = c[0]
+ colors[:, 1] = c[1]
+ colors[:, 2] = c[2]
+ # print("Single colors")
+ elif type(c) == np.ndarray and len(c.shape) == 2 and c.shape[1] == 3: # Color values for
+ if c.shape[0] == f.shape[0]: # faces
+ colors = np.hstack([c, c, c]).reshape((-1, 3))
+ coloring = "FaceColors"
+ # print("Face color values")
+ elif c.shape[0] == v.shape[0]: # vertices
+ colors = c
+ # print("Vertex color values")
+ else: # Wrong size, fallback
+ print("Invalid color array given! Supported are numpy arrays.", type(c))
+ colors = np.ones_like(v)
+ colors[:, 0] = 1.0
+ colors[:, 1] = 0.874
+ colors[:, 2] = 0.0
+ elif type(c) == np.ndarray and c.size == f.shape[0]: # Function values for faces
+ normalize = sh["normalize"][0] != None and sh["normalize"][1] != None
+ cc = get_colors(c, sh["colormap"], normalize=normalize,
+ vmin=sh["normalize"][0], vmax=sh["normalize"][1])
+ # print(cc.shape)
+ colors = np.hstack([cc, cc, cc]).reshape((-1, 3))
+ coloring = "FaceColors"
+ # print("Face function values")
+ elif type(c) == np.ndarray and c.size == v.shape[0]: # Function values for vertices
+ normalize = sh["normalize"][0] != None and sh["normalize"][1] != None
+ colors = get_colors(c, sh["colormap"], normalize=normalize,
+ vmin=sh["normalize"][0], vmax=sh["normalize"][1])
+ # print("Vertex function values")
+
+ else:
+ colors = np.ones_like(v)
+ colors[:, 0] = 1.0
+ colors[:, 1] = 0.874
+ colors[:, 2] = 0.0
+
+ # No color
+ if c is not None:
+ print("Invalid color array given! Supported are numpy arrays.", type(c))
+
+ return colors, coloring
+
+ def __get_point_colors(self, v, c, sh):
+ v_color = True
+ if c is None: # No color given, use global color
+ # conv = mpl.colors.ColorConverter()
+ colors = sh["point_color"] # np.array(conv.to_rgb(sh["point_color"]))
+ v_color = False
+ elif isinstance(c, str): # No color given, use global color
+ # conv = mpl.colors.ColorConverter()
+ colors = c # np.array(conv.to_rgb(c))
+ v_color = False
+ elif type(c) == np.ndarray and len(c.shape) == 2 and c.shape[0] == v.shape[0] and c.shape[1] == 3:
+ # Point color
+ colors = c.astype("float32", copy=False)
+
+ elif isinstance(c, np.ndarray) and len(c.shape) == 2 and c.shape[0] == v.shape[0] and c.shape[1] != 3:
+ # Function values for vertices, but the colors are features
+ c_norm = np.linalg.norm(c, ord=2, axis=-1)
+ normalize = sh["normalize"][0] != None and sh["normalize"][1] != None
+ colors = get_colors(c_norm, sh["colormap"], normalize=normalize,
+ vmin=sh["normalize"][0], vmax=sh["normalize"][1])
+ colors = colors.astype("float32", copy=False)
+
+ elif type(c) == np.ndarray and c.size == v.shape[0]: # Function color
+ normalize = sh["normalize"][0] != None and sh["normalize"][1] != None
+ colors = get_colors(c, sh["colormap"], normalize=normalize,
+ vmin=sh["normalize"][0], vmax=sh["normalize"][1])
+ colors = colors.astype("float32", copy=False)
+ # print("Vertex function values")
+
+ else:
+ print("Invalid color array given! Supported are numpy arrays.", type(c))
+ colors = sh["point_color"]
+ v_color = False
+
+ return colors, v_color
+
+ def add_mesh(self, v, f, c=None, uv=None, n=None, shading={}, texture_data=None, **kwargs):
+ shading.update(kwargs)
+ sh = self.__get_shading(shading)
+ mesh_obj = {}
+
+ # it is a tet
+ if v.shape[1] == 3 and f.shape[1] == 4:
+ f_tmp = np.ndarray([f.shape[0] * 4, 3], dtype=f.dtype)
+ for i in range(f.shape[0]):
+ f_tmp[i * 4 + 0] = np.array([f[i][1], f[i][0], f[i][2]])
+ f_tmp[i * 4 + 1] = np.array([f[i][0], f[i][1], f[i][3]])
+ f_tmp[i * 4 + 2] = np.array([f[i][1], f[i][2], f[i][3]])
+ f_tmp[i * 4 + 3] = np.array([f[i][2], f[i][0], f[i][3]])
+ f = f_tmp
+
+ if v.shape[1] == 2:
+ v = np.append(v, np.zeros([v.shape[0], 1]), 1)
+
+ # Type adjustment vertices
+ v = v.astype("float32", copy=False)
+
+ # Color setup
+ colors, coloring = self.__get_colors(v, f, c, sh)
+
+ # Type adjustment faces and colors
+ c = colors.astype("float32", copy=False)
+
+ # Material and geometry setup
+ ba_dict = {"color": p3s.BufferAttribute(c)}
+ if coloring == "FaceColors":
+ verts = np.zeros((f.shape[0] * 3, 3), dtype="float32")
+ for ii in range(f.shape[0]):
+ # print(ii*3, f[ii])
+ verts[ii * 3] = v[f[ii, 0]]
+ verts[ii * 3 + 1] = v[f[ii, 1]]
+ verts[ii * 3 + 2] = v[f[ii, 2]]
+ v = verts
+ else:
+ f = f.astype("uint32", copy=False).ravel()
+ ba_dict["index"] = p3s.BufferAttribute(f, normalized=False)
+
+ ba_dict["position"] = p3s.BufferAttribute(v, normalized=False)
+
+ if uv is not None:
+ uv = (uv - np.min(uv)) / (np.max(uv) - np.min(uv))
+ if texture_data is None:
+ texture_data = gen_checkers(20, 20)
+ tex = p3s.DataTexture(data=texture_data, format="RGBFormat", type="FloatType")
+ material = p3s.MeshStandardMaterial(map=tex, reflectivity=sh["reflectivity"], side=sh["side"],
+ roughness=sh["roughness"], metalness=sh["metalness"],
+ flatShading=sh["flat"],
+ polygonOffset=True, polygonOffsetFactor=1, polygonOffsetUnits=5)
+ ba_dict["uv"] = p3s.BufferAttribute(uv.astype("float32", copy=False))
+ else:
+ material = p3s.MeshStandardMaterial(vertexColors=coloring, reflectivity=sh["reflectivity"],
+ side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"],
+ flatShading=sh["flat"],
+ polygonOffset=True, polygonOffsetFactor=1, polygonOffsetUnits=5)
+
+ if type(n) != type(None) and coloring == "VertexColors": # TODO: properly handle normals for FaceColors as well
+ ba_dict["normal"] = p3s.BufferAttribute(n.astype("float32", copy=False), normalized=True)
+
+ geometry = p3s.BufferGeometry(attributes=ba_dict)
+
+ if coloring == "VertexColors" and type(n) == type(None):
+ geometry.exec_three_obj_method('computeVertexNormals')
+ elif coloring == "FaceColors" and type(n) == type(None):
+ geometry.exec_three_obj_method('computeFaceNormals')
+
+ # Mesh setup
+ mesh = p3s.Mesh(geometry=geometry, material=material)
+
+ # Wireframe setup
+ mesh_obj["wireframe"] = None
+ if sh["wireframe"]:
+ wf_geometry = p3s.WireframeGeometry(mesh.geometry) # WireframeGeometry
+ wf_material = p3s.LineBasicMaterial(color=sh["wire_color"], linewidth=sh["wire_width"])
+ wireframe = p3s.LineSegments(wf_geometry, wf_material)
+ mesh.add(wireframe)
+ mesh_obj["wireframe"] = wireframe
+
+ # Bounding box setup
+ if sh["bbox"]:
+ v_box, f_box = self.__get_bbox(v)
+ _, bbox = self.add_edges(v_box, f_box, sh, mesh)
+ mesh_obj["bbox"] = [bbox, v_box, f_box]
+
+ # Object setup
+ mesh_obj["max"] = np.max(v, axis=0)
+ mesh_obj["min"] = np.min(v, axis=0)
+ mesh_obj["geometry"] = geometry
+ mesh_obj["mesh"] = mesh
+ mesh_obj["material"] = material
+ mesh_obj["type"] = "Mesh"
+ mesh_obj["shading"] = sh
+ mesh_obj["coloring"] = coloring
+ mesh_obj["arrays"] = [v, f, c] # TODO replays with proper storage or remove if not needed
+
+ return self.__add_object(mesh_obj)
+
+ def add_lines(self, beginning, ending, shading={}, obj=None, **kwargs):
+ shading.update(kwargs)
+ if len(beginning.shape) == 1:
+ if len(beginning) == 2:
+ beginning = np.array([[beginning[0], beginning[1], 0]])
+ else:
+ if beginning.shape[1] == 2:
+ beginning = np.append(
+ beginning, np.zeros([beginning.shape[0], 1]), 1)
+ if len(ending.shape) == 1:
+ if len(ending) == 2:
+ ending = np.array([[ending[0], ending[1], 0]])
+ else:
+ if ending.shape[1] == 2:
+ ending = np.append(
+ ending, np.zeros([ending.shape[0], 1]), 1)
+
+ sh = self.__get_shading(shading)
+ lines = np.hstack([beginning, ending])
+ lines = lines.reshape((-1, 3))
+ return self.__add_line_geometry(lines, sh, obj)
+
+ def add_edges(self, vertices, edges, shading={}, obj=None, **kwargs):
+ shading.update(kwargs)
+ if vertices.shape[1] == 2:
+ vertices = np.append(
+ vertices, np.zeros([vertices.shape[0], 1]), 1)
+ sh = self.__get_shading(shading)
+ lines = np.zeros((edges.size, 3))
+ cnt = 0
+ for e in edges:
+ lines[cnt, :] = vertices[e[0]]
+ lines[cnt + 1, :] = vertices[e[1]]
+ cnt += 2
+ return self.__add_line_geometry(lines, sh, obj)
+
+ def add_points(self, points, c=None, shading={}, obj=None, **kwargs):
+ shading.update(kwargs)
+ if len(points.shape) == 1:
+ if len(points) == 2:
+ points = np.array([[points[0], points[1], 0]])
+ else:
+ if points.shape[1] == 2:
+ points = np.append(
+ points, np.zeros([points.shape[0], 1]), 1)
+ sh = self.__get_shading(shading)
+ points = points.astype("float32", copy=False)
+ mi = np.min(points, axis=0)
+ ma = np.max(points, axis=0)
+
+ g_attributes = {"position": p3s.BufferAttribute(points, normalized=False)}
+ m_attributes = {"size": sh["point_size"]}
+
+ if sh["point_shape"] == "circle": # Plot circles
+ tex = p3s.DataTexture(data=gen_circle(16, 16), format="RGBAFormat", type="FloatType")
+ m_attributes["map"] = tex
+ m_attributes["alphaTest"] = 0.5
+ m_attributes["transparency"] = True
+ else: # Plot squares
+ pass
+
+ colors, v_colors = self.__get_point_colors(points, c, sh)
+ if v_colors: # Colors per point
+ m_attributes["vertexColors"] = 'VertexColors'
+ g_attributes["color"] = p3s.BufferAttribute(colors, normalized=False)
+
+ else: # Colors for all points
+ m_attributes["color"] = colors
+
+ material = p3s.PointsMaterial(**m_attributes)
+ geometry = p3s.BufferGeometry(attributes=g_attributes)
+ points = p3s.Points(geometry=geometry, material=material)
+ point_obj = {"geometry": geometry, "mesh": points, "material": material,
+ "max": ma, "min": mi, "type": "Points", "wireframe": None}
+
+ if obj:
+ return self.__add_object(point_obj, obj), point_obj
+ else:
+ return self.__add_object(point_obj)
+
+ def remove_object(self, obj_id):
+ if obj_id not in self.__objects:
+ print("Invalid object id. Valid ids are: ", list(self.__objects.keys()))
+ return
+ self._scene.remove(self.__objects[obj_id]["mesh"])
+ del self.__objects[obj_id]
+ self.__update_view()
+
+ def reset(self):
+ for obj_id in list(self.__objects.keys()).copy():
+ self._scene.remove(self.__objects[obj_id]["mesh"])
+ del self.__objects[obj_id]
+ self.__update_view()
+
+ def update_object(self, oid=0, vertices=None, colors=None, faces=None):
+ obj = self.__objects[oid]
+ if type(vertices) != type(None):
+ if obj["coloring"] == "FaceColors":
+ f = obj["arrays"][1]
+ verts = np.zeros((f.shape[0] * 3, 3), dtype="float32")
+ for ii in range(f.shape[0]):
+ # print(ii*3, f[ii])
+ verts[ii * 3] = vertices[f[ii, 0]]
+ verts[ii * 3 + 1] = vertices[f[ii, 1]]
+ verts[ii * 3 + 2] = vertices[f[ii, 2]]
+ v = verts
+
+ else:
+ v = vertices.astype("float32", copy=False)
+ obj["geometry"].attributes["position"].array = v
+ # self.wireframe.attributes["position"].array = v # Wireframe updates?
+ obj["geometry"].attributes["position"].needsUpdate = True
+ # obj["geometry"].exec_three_obj_method('computeVertexNormals')
+ if type(colors) != type(None):
+ colors, coloring = self.__get_colors(obj["arrays"][0], obj["arrays"][1], colors, obj["shading"])
+ colors = colors.astype("float32", copy=False)
+ obj["geometry"].attributes["color"].array = colors
+ obj["geometry"].attributes["color"].needsUpdate = True
+ if type(faces) != type(None):
+ if obj["coloring"] == "FaceColors":
+ print("Face updates are currently only possible in vertex color mode.")
+ return
+ f = faces.astype("uint32", copy=False).ravel()
+ print(obj["geometry"].attributes)
+ obj["geometry"].attributes["index"].array = f
+ # self.wireframe.attributes["position"].array = v # Wireframe updates?
+ obj["geometry"].attributes["index"].needsUpdate = True
+ # obj["geometry"].exec_three_obj_method('computeVertexNormals')
+ # self.mesh.geometry.verticesNeedUpdate = True
+ # self.mesh.geometry.elementsNeedUpdate = True
+ # self.update()
+ if self.render_mode == "WEBSITE":
+ return self
+
+ # def update(self):
+ # self.mesh.exec_three_obj_method('update')
+ # self.orbit.exec_three_obj_method('update')
+ # self.cam.exec_three_obj_method('updateProjectionMatrix')
+ # self.scene.exec_three_obj_method('update')
+
+ def add_text(self, text, shading={}, **kwargs):
+ shading.update(kwargs)
+ sh = self.__get_shading(shading)
+ tt = p3s.TextTexture(string=text, color=sh["text_color"])
+ sm = p3s.SpriteMaterial(map=tt)
+ text = p3s.Sprite(material=sm, scaleToTexture=True)
+ self._scene.add(text)
+
+ # def add_widget(self, widget, callback):
+ # self.widgets.append(widget)
+ # widget.observe(callback, names='value')
+
+ # def add_dropdown(self, options, default, desc, cb):
+ # widget = widgets.Dropdown(options=options, value=default, description=desc)
+ # self.__widgets.append(widget)
+ # widget.observe(cb, names="value")
+ # display(widget)
+
+ # def add_button(self, text, cb):
+ # button = widgets.Button(description=text)
+ # self.__widgets.append(button)
+ # button.on_click(cb)
+ # display(button)
+
+ def to_html(self, imports=True, html_frame=True):
+ # Bake positions (fixes centering bug in offline rendering)
+ if len(self.__objects) == 0:
+ return
+ ma = np.zeros((len(self.__objects), 3))
+ mi = np.zeros((len(self.__objects), 3))
+ for r, obj in enumerate(self.__objects):
+ ma[r] = self.__objects[obj]["max"]
+ mi[r] = self.__objects[obj]["min"]
+ ma = np.max(ma, axis=0)
+ mi = np.min(mi, axis=0)
+ diag = np.linalg.norm(ma - mi)
+ mean = (ma - mi) / 2 + mi
+ for r, obj in enumerate(self.__objects):
+ v = self.__objects[obj]["geometry"].attributes["position"].array
+ v -= mean
+ # v += np.array([0.0, .9, 0.0]) #! to move the obj to the center of window
+
+ scale = self.__s["scale"] * (diag)
+ self._orbit.target = [0.0, 0.0, 0.0]
+ self._cam.lookAt([0.0, 0.0, 0.0])
+ # self._cam.position = [0.0, 0.0, scale]
+ self._cam.position = [0.0, 0.5, scale * 1.3] #! show four complete meshes in the window
+ self._light.position = [0.0, 0.0, scale]
+
+ state = embed.dependency_state(self._renderer)
+
+ # Somehow these entries are missing when the state is exported in python.
+ # Exporting from the GUI works, so we are inserting the missing entries.
+ for k in state:
+ if state[k]["model_name"] == "OrbitControlsModel":
+ state[k]["state"]["maxAzimuthAngle"] = "inf"
+ state[k]["state"]["maxDistance"] = "inf"
+ state[k]["state"]["maxZoom"] = "inf"
+ state[k]["state"]["minAzimuthAngle"] = "-inf"
+
+ tpl = embed.load_requirejs_template
+ if not imports:
+ embed.load_requirejs_template = ""
+
+ s = embed.embed_snippet(self._renderer, state=state, embed_url=EMBED_URL)
+ # s = embed.embed_snippet(self.__w, state=state)
+ embed.load_requirejs_template = tpl
+
+ if html_frame:
+ s = "\n\n" + s + "\n\n"
+
+ # Revert changes
+ for r, obj in enumerate(self.__objects):
+ v = self.__objects[obj]["geometry"].attributes["position"].array
+ v += mean
+ self.__update_view()
+
+ return s
+
+ def save(self, filename=""):
+ if filename == "":
+ uid = str(uuid.uuid4()) + ".html"
+ else:
+ filename = filename.replace(".html", "")
+ uid = filename + '.html'
+ with open(uid, "w") as f:
+ f.write(self.to_html())
+ print("Plot saved to file %s." % uid)
diff --git a/Hunyuan3D-2.1/hy3dshape/main.py b/Hunyuan3D-2.1/hy3dshape/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c1ae51f61e2578dad8ee93e99c2df150968cc73
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/main.py
@@ -0,0 +1,209 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from typing import Tuple, List
+import warnings
+warnings.filterwarnings("ignore")
+
+import os
+import torch
+import argparse
+from pathlib import Path
+from omegaconf import OmegaConf, DictConfig
+from einops._torch_specific import allow_ops_in_compiled_graph # requires einops>=0.6.1
+allow_ops_in_compiled_graph()
+
+import pytorch_lightning as pl
+from pytorch_lightning.callbacks import ModelCheckpoint, Callback
+from pytorch_lightning.strategies import DDPStrategy, DeepSpeedStrategy
+from pytorch_lightning.loggers import Logger, TensorBoardLogger
+from pytorch_lightning.utilities import rank_zero_info
+
+from hy3dshape.utils import get_config_from_file, instantiate_from_config
+
+
+class SetupCallback(Callback):
+ def __init__(self, config: DictConfig, basedir: Path, logdir: str = "log", ckptdir: str = "ckpt") -> None:
+ super().__init__()
+ self.logdir = basedir / logdir
+ self.ckptdir = basedir / ckptdir
+ self.config = config
+
+ def on_fit_start(self, trainer: pl.trainer.Trainer, pl_module: pl.LightningModule) -> None:
+ if trainer.global_rank == 0:
+ os.makedirs(self.logdir, exist_ok=True)
+ os.makedirs(self.ckptdir, exist_ok=True)
+
+
+def setup_callbacks(config: DictConfig) -> Tuple[List[Callback], Logger]:
+ training_cfg = config.training
+ basedir = Path(training_cfg.output_dir)
+ os.makedirs(basedir, exist_ok=True)
+ all_callbacks = []
+
+ setup_callback = SetupCallback(config, basedir)
+ all_callbacks.append(setup_callback)
+
+ checkpoint_callback = ModelCheckpoint(
+ dirpath=setup_callback.ckptdir,
+ filename="ckpt-{step:08d}",
+ monitor=training_cfg.monitor,
+ mode="max",
+ save_top_k=-1,
+ verbose=False,
+ every_n_train_steps=training_cfg.every_n_train_steps)
+ all_callbacks.append(checkpoint_callback)
+
+ if "callbacks" in config:
+ for key, value in config['callbacks'].items():
+ custom_callback = instantiate_from_config(value)
+ all_callbacks.append(custom_callback)
+
+ logger = TensorBoardLogger(save_dir=str(setup_callback.logdir), name="tensorboard")
+
+ return all_callbacks, logger
+
+
+def merge_cfg(cfg, arg_cfg):
+ for key in arg_cfg.keys():
+ if key in cfg.training:
+ arg_cfg[key] = cfg.training[key]
+ cfg.training = DictConfig(arg_cfg)
+ return cfg
+
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--fast", action='store_true')
+ parser.add_argument("-c", "--config", type=str, required=True)
+ parser.add_argument("-s", "--seed", type=int, default=0)
+ parser.add_argument("-nn", "--num_nodes", type=int, default=1)
+ parser.add_argument("-ng", "--num_gpus", type=int, default=1)
+ parser.add_argument("-u", "--update_every", type=int, default=1)
+ parser.add_argument("-st", "--steps", type=int, default=50000000)
+ parser.add_argument("-lr", "--base_lr", type=float, default=4.5e-6)
+ parser.add_argument("-a", "--use_amp", default=False, action="store_true")
+ parser.add_argument("--amp_type", type=str, default="16")
+ parser.add_argument("--gradient_clip_val", type=float, default=None)
+ parser.add_argument("--gradient_clip_algorithm", type=str, default=None)
+ parser.add_argument("--every_n_train_steps", type=int, default=50000)
+ parser.add_argument("--log_every_n_steps", type=int, default=50)
+ parser.add_argument("--val_check_interval", type=int, default=1024)
+ parser.add_argument("--limit_val_batches", type=int, default=64)
+ parser.add_argument("--monitor", type=str, default="val/total_loss")
+ parser.add_argument("--output_dir", type=str, help="the output directory to save everything.")
+ parser.add_argument("--ckpt_path", type=str, default="", help="the restore checkpoints.")
+ parser.add_argument("--deepspeed", default=False, action="store_true")
+ parser.add_argument("--deepspeed2", default=False, action="store_true")
+ parser.add_argument("--scale_lr", type=bool, nargs="?", const=True, default=False,
+ help="scale base-lr by ngpu * batch_size * n_accumulate")
+ return parser.parse_args()
+
+
+if __name__ == "__main__":
+
+ args = get_args()
+
+ if args.fast:
+ torch.backends.cudnn.allow_tf32 = True
+ torch.backends.cuda.matmul.allow_tf32 = True
+ torch.set_float32_matmul_precision('medium')
+ torch.utils.data._utils.MP_STATUS_CHECK_INTERVAL = 0.05
+
+ # Set random seed
+ pl.seed_everything(args.seed, workers=True)
+
+ # Load configuration
+ config = get_config_from_file(args.config)
+ config = merge_cfg(config, vars(args))
+ training_cfg = config.training
+
+ # print config
+ rank_zero_info("Begin to print configuration ...")
+ rank_zero_info(OmegaConf.to_yaml(config))
+ rank_zero_info("Finish print ...")
+
+ # Setup callbacks
+ callbacks, loggers = setup_callbacks(config)
+
+ # Build data modules
+ data: pl.LightningDataModule = instantiate_from_config(config.dataset)
+
+ # Build model
+ model: pl.LightningModule = instantiate_from_config(config.model)
+
+ nodes = args.num_nodes
+ ngpus = args.num_gpus
+ base_lr = training_cfg.base_lr
+ accumulate_grad_batches = training_cfg.update_every
+ batch_size = config.dataset.params.batch_size
+
+ if 'NNODES' in os.environ:
+ nodes = int(os.environ['NNODES'])
+ training_cfg.num_nodes = nodes
+ args.num_nodes = nodes
+
+ if args.scale_lr:
+ model.learning_rate = accumulate_grad_batches * nodes * ngpus * batch_size * base_lr
+ info = f"Setting learning rate to {model.learning_rate:.2e} = {accumulate_grad_batches} (accumulate)"
+ info += f" * {nodes} (nodes) * {ngpus} (num_gpus) * {batch_size} (batchsize) * {base_lr:.2e} (base_lr)"
+ rank_zero_info(info)
+ else:
+ model.learning_rate = base_lr
+ rank_zero_info("++++ NOT USING LR SCALING ++++")
+ rank_zero_info(f"Setting learning rate to {model.learning_rate:.2e}")
+
+ # Build trainer
+ if args.num_nodes > 1 or args.num_gpus > 1:
+ if args.deepspeed:
+ ddp_strategy = DeepSpeedStrategy(stage=1)
+ elif args.deepspeed2:
+ ddp_strategy = 'deepspeed_stage_2'
+ else:
+ ddp_strategy = DDPStrategy(find_unused_parameters=False, bucket_cap_mb=1500)
+ else:
+ ddp_strategy = None # 'auto'
+
+ rank_zero_info(f'*' * 100)
+ if training_cfg.use_amp:
+ amp_type = training_cfg.amp_type
+ assert amp_type in ['bf16', '16', '32'], f"Invalid amp_type: {amp_type}"
+ rank_zero_info(f'Using {amp_type} precision')
+ else:
+ amp_type = 32
+ rank_zero_info(f'Using 32 bit precision')
+ rank_zero_info(f'*' * 100)
+
+ trainer = pl.Trainer(
+ max_steps=training_cfg.steps,
+ precision=amp_type,
+ callbacks=callbacks,
+ accelerator="gpu",
+ devices=training_cfg.num_gpus,
+ num_nodes=training_cfg.num_nodes,
+ strategy=ddp_strategy,
+ gradient_clip_val=training_cfg.get('gradient_clip_val'),
+ gradient_clip_algorithm=training_cfg.get('gradient_clip_algorithm'),
+ accumulate_grad_batches=args.update_every,
+ logger=loggers,
+ log_every_n_steps=training_cfg.log_every_n_steps,
+ val_check_interval=training_cfg.val_check_interval,
+ limit_val_batches=training_cfg.limit_val_batches,
+ check_val_every_n_epoch=None
+ )
+
+ # Train
+ if training_cfg.ckpt_path == '':
+ training_cfg.ckpt_path = None
+ trainer.fit(model, datamodule=data, ckpt_path=training_cfg.ckpt_path)
diff --git a/Hunyuan3D-2.1/hy3dshape/minimal_demo.py b/Hunyuan3D-2.1/hy3dshape/minimal_demo.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4bfe8fe49e866e2d66b3a7b44cfd6dbfe21fd92
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/minimal_demo.py
@@ -0,0 +1,30 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+from PIL import Image
+
+from hy3dshape.rembg import BackgroundRemover
+from hy3dshape.pipelines import Hunyuan3DDiTFlowMatchingPipeline
+
+model_path = 'tencent/Hunyuan3D-2.1'
+pipeline_shapegen = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained(model_path)
+
+image_path = 'demos/demo.png'
+image = Image.open(image_path).convert("RGBA")
+if image.mode == 'RGB':
+ rembg = BackgroundRemover()
+ image = rembg(image)
+
+mesh = pipeline_shapegen(image=image)[0]
+mesh.export('demo.glb')
diff --git a/Hunyuan3D-2.1/hy3dshape/minimal_vae_demo.py b/Hunyuan3D-2.1/hy3dshape/minimal_vae_demo.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b398cb7e37fa2a81b930a35b2bb70cd293707df
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/minimal_vae_demo.py
@@ -0,0 +1,51 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import torch
+
+from hy3dshape.surface_loaders import SharpEdgeSurfaceLoader
+from hy3dshape.models.autoencoders import ShapeVAE
+from hy3dshape.pipelines import export_to_trimesh
+
+
+vae = ShapeVAE.from_pretrained(
+ 'tencent/Hunyuan3D-2.1',
+ use_safetensors=False,
+ variant='fp16',
+)
+
+
+loader = SharpEdgeSurfaceLoader(
+ num_sharp_points=0,
+ num_uniform_points=81920,
+)
+mesh_demo = 'demos/demo.glb'
+surface = loader(mesh_demo).to('cuda', dtype=torch.float16)
+print(surface.shape)
+
+latents = vae.encode(surface)
+latents = vae.decode(latents)
+mesh = vae.latents2mesh(
+ latents,
+ output_type='trimesh',
+ bounds=1.01,
+ mc_level=0.0,
+ num_chunks=20000,
+ octree_resolution=256,
+ mc_algo='mc',
+ enable_pbar=True
+)
+
+mesh = export_to_trimesh(mesh)[0]
+mesh.export('output.obj')
diff --git a/Hunyuan3D-2.1/hy3dshape/requirements.txt b/Hunyuan3D-2.1/hy3dshape/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..abdab84e043a82dc588767e52e925971dd183d4f
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/requirements.txt
@@ -0,0 +1,40 @@
+ninja
+pybind11
+
+diffusers
+einops
+opencv-python
+numpy
+torch
+transformers
+torchvision
+#taming-transformers-rom1504
+#ConfigArgParse
+#ipdb
+omegaconf
+
+#sentencepiece
+tqdm
+
+# Mesh Processing
+trimesh
+pymeshlab
+pygltflib
+xatlas
+#kornia
+#facexlib
+
+# Training
+accelerate
+#pytorch_lightning
+#scikit-learn
+#scikit-image
+
+# Demo only
+gradio
+fastapi
+uvicorn
+rembg
+onnxruntime
+#gevent
+#geventhttpclient
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/scripts/train_deepspeed.sh b/Hunyuan3D-2.1/hy3dshape/scripts/train_deepspeed.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ed6b7c7c3b8dded37891016fe6bcbab3fb9ba282
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/scripts/train_deepspeed.sh
@@ -0,0 +1,70 @@
+# If: ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found
+# Do: ln /usr/local/gcc-8.3/lib64/libstdc++.so.6 -sf /usr/lib64/libstdc++.so.6
+
+export NCCL_IB_TIMEOUT=24
+export NCCL_NVLS_ENABLE=0
+NET_TYPE="high"
+if [[ "${NET_TYPE}" = "low" ]]; then
+ export NCCL_SOCKET_IFNAME=eth1
+ export NCCL_IB_GID_INDEX=3
+ export NCCL_IB_HCA=mlx5_2:1,mlx5_2:1
+ export NCCL_IB_SL=3
+ export NCCL_CHECK_DISABLE=1
+ export NCCL_P2P_DISABLE=0
+ export NCCL_LL_THRESHOLD=16384
+ export NCCL_IB_CUDA_SUPPORT=1
+else
+ export NCCL_IB_GID_INDEX=3
+ export NCCL_IB_SL=3
+ export NCCL_CHECK_DISABLE=1
+ export NCCL_P2P_DISABLE=0
+ export NCCL_IB_DISABLE=0
+ export NCCL_LL_THRESHOLD=16384
+ export NCCL_IB_CUDA_SUPPORT=1
+ export NCCL_SOCKET_IFNAME=bond1
+ export UCX_NET_DEVICES=bond1
+ export NCCL_IB_HCA=mlx5_bond_1,mlx5_bond_5,mlx5_bond_3,mlx5_bond_7,mlx5_bond_4,mlx5_bond_8,mlx5_bond_2,mlx5_bond_6
+ export NCCL_COLLNET_ENABLE=0
+ export SHARP_COLL_ENABLE_SAT=0
+ export NCCL_NET_GDR_LEVEL=2
+ export NCCL_IB_QPS_PER_CONNECTION=4
+ export NCCL_IB_TC=160
+ export NCCL_PXN_DISABLE=0
+fi
+export NCCL_DEBUG=WARN
+
+node_num=$1
+node_rank=$2
+master_ip=$3
+config=$4
+output_dir=$5
+
+# config='configs/dit-from-scratch-overfitting-flowmatching-dinog518-bf16-lr1e4-1024.yaml'
+# output_dir='output_folder/dit/overfitting_10'
+
+echo node_num $node_num
+echo node_rank $node_rank
+echo master_ip $master_ip
+echo config $config
+echo output_dir $output_dir
+
+if test -d "$output_dir"; then
+ cp $config $output_dir
+else
+ mkdir -p "$output_dir"
+ cp $config $output_dir
+fi
+
+NODE_RANK=$node_rank \
+HF_HUB_OFFLINE=0 \
+MASTER_PORT=12348 \
+MASTER_ADDR=$master_ip \
+NCCL_SOCKET_IFNAME=bond1 \
+NCCL_IB_GID_INDEX=3 \
+NCCL_NVLS_ENABLE=0 \
+python3 main.py \
+ --num_nodes $node_num \
+ --num_gpus 8 \
+ --config $config \
+ --output_dir $output_dir \
+ --deepspeed
diff --git a/Hunyuan3D-2.1/hy3dshape/tools/README-ch.md b/Hunyuan3D-2.1/hy3dshape/tools/README-ch.md
new file mode 100644
index 0000000000000000000000000000000000000000..af1c480aef1b6381e424608c52e2f794cd984b92
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/tools/README-ch.md
@@ -0,0 +1,94 @@
+# 数据处理
+
+这是用于3D形状和纹理生成的数据处理流程。
+
+**注意事项**:
+1. 该实现是我们工业流程的简化版本。
+2. 渲染脚本基于[TRELLIS](https://github.com/microsoft/TRELLIS/blob/main/dataset_toolkits/blender_script/render.py)。
+
+## 渲染
+
+### 动机
+渲染脚本`render/render.py`主要有三个目的:
+1. 使用Blender将复杂的3D格式转换为PLY文件,以便进行进一步处理。
+2. 为DiT训练渲染条件图像。
+3. 渲染正交图像、PBR材质以及用于纹理生成的条件信号(世界空间法线和位置)。
+
+### 需求
+渲染脚本使用Blender 4.1执行。你需要使用Blender的Python安装`opencv`、`OpenEXR`和`Imath`。以下是Macbook上的示例:
+```bash
+/Applications/Blender.app/Contents/Resources/4.1/python/bin/python3.11 -m pip install OpenEXR Imath opencv-python
+```
+
+### 执行
+前两个目的可以通过以下单一命令执行:
+```bash
+$BLENDER_PATH -b -P render/render.py -- \
+ --object ${INPUT_FILE} --geo_mode --resolution 512 \
+ --output_folder $OUTPUT_FOLDER
+```
+对于第三个目的,只需移除`--geo_mode`标志。
+
+## 水密网格处理和采样
+
+### 动机
+为了学习3DShape2VecSets的SDF表示,我们需要一个水密输入网格。该流程处理原始三角网格,生成三种必要的数据类型:
+1. **表面采样** - 编码器的输入点。
+2. **体积采样** - 解码器中SDF评估的查询点。
+3. **体积SDFs** - VAE训练的地面真实有符号距离值。
+
+### 执行
+处理三角网格(OBJ/OFF格式),生成以下内容:
+1. 水密网格(`${OUTPUT_NAME}_watertight.obj`)。
+2. 表面点采样(`${OUTPUT_NAME}_surface.npz`)。
+3. 带有SDF的体积采样(`${OUTPUT_NAME}_sdf.npz`)。
+
+**命令:**
+```bash
+python3 watertight/watertight_and_sample.py \
+ --input_obj ${INPUT_MESH} \
+ --output_prefix ${OUTPUT_NAME}
+```
+
+### 输出数据格式
+
+#### 1. 表面采样(`${OUTPUT_NAME}_surface.npz`)
+包含两个点云数组,以numpy NPZ格式存储:
+
+| 键 | 形状 | 格式 | 描述 |
+|-----------------|----------|----------|---------------------------------|
+| `random_surface` | `(N, 6)` | `float16`| 表面上的均匀点采样 |
+| `sharp_surface` | `(M, 6)` | `float16`| 靠近网格锐边的采样 |
+
+#### 2. 体积SDF采样(`${OUTPUT_NAME}_sdf.npz`)
+包含三种采样类型,以数组对的形式存储。对于每种类型`${type}`:
+
+| 采样类型 | 点数组 | SDF标签数组 | 形状 | 格式 | 描述 |
+|-----------------|----------------------|----------------------|----------|----------|-------------------------|
+| `vol` | `vol_points` | `vol_label` | `(P, 3)/(P,)` | `float16`| 随机空间采样 |
+| `random_near` | `random_near_points` | `random_near_label` | `(Q, 3)/(Q,)` | `float16`| 靠近表面的采样 |
+| `sharp_near` | `sharp_near_points` | `sharp_near_label` | `(R, 3)/(R,)` | `float16`| 靠近锐边的采样 |
+
+**数据规格**:
+- 所有点坐标(`*_points`数组)包含以`float16`值存储的3D位置。
+- 所有SDF值(`*_label`数组)是表示以下内容的`float16`标量:
+ - **正值**:在表面外。
+ - **负值**:在表面内。
+ - **零值**:在表面上。
+- 数组维度:
+ - `N`、`M`、`P`、`Q`、`R`表示采样数量(因形状而异)。
+ - `3`表示XYZ坐标。
+ - `6`表示XYZ/法线坐标。
+- 所有数组均以未压缩形式存储在numpy的NPZ格式中。
+
+## 整体脚本
+修改pipeline.sh里面这4个变量,
+1. **INPUT_FILE** 每个3D数据的路径。
+2. **OUTPUT_FOLDER** 输出数据集的总路径。
+3. **NAME** 每个数据的输出路径命名。
+4. **BLENDER_PATH** Blender可执行路径。
+
+然后运行以下脚本:
+```bash
+bash pipeline.sh
+```
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/tools/README.md b/Hunyuan3D-2.1/hy3dshape/tools/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..38b70546fe2ec922ce735fdc89360aa2770e450e
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/tools/README.md
@@ -0,0 +1,94 @@
+# Data Processing
+
+This is the data processing pipeline for 3D shape and texture generation.
+
+**Notes**:
+1. This implementation is a simplified version of our industrial pipeline.
+2. The rendering script is based on [TRELLIS](https://github.com/microsoft/TRELLIS/blob/main/dataset_toolkits/blender_script/render.py).
+
+## Rendering
+
+### Motivation
+The rendering script `render/render.py` serves three main purposes:
+1. Converting complex 3D formats to PLY files using Blender for further processing.
+2. Rendering condition images for DiT training.
+3. Rendering orthogonal images, PBR materials, and conditional signals (world-space normals and positions) for texture generation.
+
+### Requirements
+The rendering scripts are executed with Blender 4.1. You need to install `opencv`, `OpenEXR`, and `Imath` using Blender's Python. Here is an example for a Macbook:
+```bash
+/Applications/Blender.app/Contents/Resources/4.1/python/bin/python3.11 -m pip install OpenEXR Imath opencv-python
+```
+
+### Execution
+The first two purposes can be executed with a single command:
+```bash
+$BLENDER_PATH -b -P render/render.py -- \
+ --object ${INPUT_FILE} --geo_mode --resolution 512 \
+ --output_folder $OUTPUT_FOLDER
+```
+For the third purpose, simply remove the `--geo_mode` flag.
+
+## Watertight Mesh Processing and Sampling
+
+### Motivation
+To learn an SDF representation for 3DShape2VecSets, we require a watertight input mesh. This pipeline processes raw triangle meshes to generate three essential data types:
+1. **Surface samples** - Input points for the encoder.
+2. **Volume samples** - Query points for SDF evaluation in the decoder.
+3. **Volume SDFs** - Ground-truth signed distance values for VAE training.
+
+### Execution
+Process a triangle mesh (OBJ/OFF format) to generate:
+1. Watertight mesh (`${OUTPUT_NAME}_watertight.obj`).
+2. Surface point samples (`${OUTPUT_NAME}_surface.npz`).
+3. Volume samples with SDFs (`${OUTPUT_NAME}_sdf.npz`).
+
+**Command:**
+```bash
+python3 watertight/watertight_and_sample.py \
+ --input_obj ${INPUT_MESH} \
+ --output_prefix ${OUTPUT_NAME}
+```
+
+### Output Data Format
+
+#### 1. Surface Samples (`${OUTPUT_NAME}_surface.npz`)
+Contains two point cloud arrays in numpy NPZ format:
+
+| Key | Shape | Format | Description |
+|-----------------|----------|----------|---------------------------------|
+| `random_surface` | `(N, 6)` | `float16`| Uniform point samples on surface |
+| `sharp_surface` | `(M, 6)` | `float16`| Samples near sharp mesh edges |
+
+#### 2. Volume SDF Samples (`${OUTPUT_NAME}_sdf.npz`)
+Contains three sample types stored as array pairs. For each type `${type}`:
+
+| Sample Type | Points Array | SDF Labels Array | Shape | Format | Description |
+|-----------------|----------------------|----------------------|----------|----------|-------------------------|
+| `vol` | `vol_points` | `vol_label` | `(P, 3)/(P,)` | `float16`| Random spatial samples |
+| `random_near` | `random_near_points` | `random_near_label` | `(Q, 3)/(Q,)` | `float16`| Samples near surface |
+| `sharp_near` | `sharp_near_points` | `sharp_near_label` | `(R, 3)/(R,)` | `float16`| Samples near sharp edges |
+
+**Data Specifications**:
+- All point coordinates (`*_points` arrays) contain 3D positions stored as `float16` values.
+- All SDF values (`*_label` arrays) are `float16` scalars representing:
+ - **Positive values**: Outside the surface.
+ - **Negative values**: Inside the surface.
+ - **Zero values**: On the surface.
+- Array dimensions:
+ - `N`, `M`, `P`, `Q`, `R` represent sample counts (vary per shape).
+ - `3` indicates XYZ coordinates.
+ - `6` indicates XYZ/Normal coordinates.
+- All arrays are stored uncompressed in numpy's NPZ format.
+
+## Overall Script
+Modify the first four variables in `pipeline.sh`:
+1. **INPUT_FILE** The path to each 3D data file.
+2. **OUTPUT_FOLDER** The overall path for the output dataset.
+3. **NAME** The naming for the output path of each data.
+4. **BLENDER_PATH** The executable path for Blender.
+
+Then run the following script:
+```bash
+bash pipeline.sh
+```
\ No newline at end of file
diff --git a/Hunyuan3D-2.1/hy3dshape/tools/pipeline.sh b/Hunyuan3D-2.1/hy3dshape/tools/pipeline.sh
new file mode 100644
index 0000000000000000000000000000000000000000..01d24785d9c6a8241f00023faf8be1880a57b1e7
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/tools/pipeline.sh
@@ -0,0 +1,10 @@
+export OPENCV_IO_ENABLE_OPENEXR=1
+export OUTPUT_FOLDER=dataset/preprocessed
+export BLENDER_PATH=/path/to/blender-4.0.2-linux-x64/blender
+
+export INPUT_FILE=dataset/raw/uuid.glb
+export NAME=uuid
+
+$BLENDER_PATH -b -P render/render.py -- --object ${INPUT_FILE} --output_folder $OUTPUT_FOLDER/$NAME/render_cond --geo_mode --resolution 512
+# $BLENDER_PATH -b -P render/render.py -- --object ${INPUT_FILE} --output_folder $OUTPUT_FOLDER/$NAME/render_tex --resolution 512
+python3 watertight/watertight_and_sample.py --input_obj $OUTPUT_FOLDER/$NAME/render_cond/mesh.ply --output_prefix $OUTPUT_FOLDER/$NAME/geo_data/$NAME
diff --git a/Hunyuan3D-2.1/hy3dshape/tools/render/render.py b/Hunyuan3D-2.1/hy3dshape/tools/render/render.py
new file mode 100644
index 0000000000000000000000000000000000000000..17011e6e825b3f7977f910812bc59eda9f0c98b2
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/tools/render/render.py
@@ -0,0 +1,925 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+
+import argparse, sys, os, math, re, glob
+from typing import *
+import bpy
+from mathutils import Vector, Matrix
+import numpy as np
+import json
+import glob
+import random
+import shutil
+import mathutils
+import cv2
+
+"""=============== BLENDER ==============="""
+
+IMPORT_FUNCTIONS: Dict[str, Callable] = {
+ "obj": bpy.ops.import_scene.obj,
+ "glb": bpy.ops.import_scene.gltf,
+ "gltf": bpy.ops.import_scene.gltf,
+ "usd": bpy.ops.import_scene.usd,
+ "fbx": bpy.ops.import_scene.fbx,
+ "stl": bpy.ops.import_mesh.stl,
+ "usda": bpy.ops.import_scene.usda,
+ "dae": bpy.ops.wm.collada_import,
+ "ply": bpy.ops.import_mesh.ply,
+ "abc": bpy.ops.wm.alembic_import,
+ "blend": bpy.ops.wm.append,
+}
+
+EXT = {
+ 'PNG': 'png',
+ 'JPEG': 'jpg',
+ 'OPEN_EXR': 'exr',
+ 'TIFF': 'tiff',
+ 'BMP': 'bmp',
+ 'HDR': 'hdr',
+ 'TARGA': 'tga'
+}
+
+PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]
+
+def radical_inverse(base, n):
+ val = 0
+ inv_base = 1.0 / base
+ inv_base_n = inv_base
+ while n > 0:
+ digit = n % base
+ val += digit * inv_base_n
+ n //= base
+ inv_base_n *= inv_base
+ return val
+
+def halton_sequence(dim, n):
+ return [radical_inverse(PRIMES[dim], n) for dim in range(dim)]
+
+def hammersley_sequence(dim, n, num_samples):
+ return [n / num_samples] + halton_sequence(dim - 1, n)
+
+def sphere_hammersley_sequence(n, num_samples, offset=(0, 0)):
+ u, v = hammersley_sequence(2, n, num_samples)
+ u += offset[0] / num_samples
+ v += offset[1]
+ u = 2 * u if u < 0.25 else 2 / 3 * u + 1 / 3
+ theta = np.arccos(1 - 2 * u) - np.pi / 2
+ phi = v * 2 * np.pi
+ return [phi, theta]
+
+def trellis_cond_camera_sequence(num_cond_views):
+ yaws = []
+ pitchs = []
+ offset = (np.random.rand(), np.random.rand())
+ for i in range(num_cond_views):
+ y, p = sphere_hammersley_sequence(i, num_cond_views, offset)
+ yaws.append(y)
+ pitchs.append(p)
+ fov_min, fov_max = 10, 70
+ radius_min = np.sqrt(3) / 2 / np.sin(fov_max / 360 * np.pi)
+ radius_max = np.sqrt(3) / 2 / np.sin(fov_min / 360 * np.pi)
+ k_min = 1 / radius_max**2
+ k_max = 1 / radius_min**2
+ ks = np.random.uniform(k_min, k_max, (1000000,))
+ radius = [1 / np.sqrt(k) for k in ks]
+ fov = [2 * np.arcsin(np.sqrt(3) / 2 / r) for r in radius]
+
+ views = [{'hangle': y, 'vangle': p, 'cam_dis': r, 'fov': f, 'proj_type': 0} \
+ for y, p, r, f in zip(yaws, pitchs, radius, fov)]
+ return views
+
+def orthogonal_camera_sequence():
+ yaws = [-0.5 * np.pi, 0, 0.5 * np.pi, np.pi, -0.5 * np.pi, -0.5 * np.pi]
+ pitchs = [0, 0, 0, 0, 0.5 * np.pi, -0.5 * np.pi]
+ radius = [1.5 for i in range(6)]
+ fov = [1.5 * np.arcsin(np.sqrt(3) / 2 / r) for r in radius]
+ views = [{'hangle': y, 'vangle': p, 'cam_dis': r, 'fov': f, 'proj_type': 1} \
+ for y, p, r, f in zip(yaws, pitchs, radius, fov)]
+ return views
+
+
+def switch_to_mr_render(render_base_color, output_nodes):
+ bpy.context.scene.view_settings.view_transform = 'Raw'
+ bpy.context.scene.use_nodes = True
+ tree = bpy.context.scene.node_tree
+ links = tree.links
+
+ for i in range(len(output_nodes)):
+ if i + 1 != len(output_nodes):
+ for l in output_nodes[i][1].links:
+ links.remove(l)
+ else:
+ links.new(output_nodes[i][0], output_nodes[i][1])
+
+ for material in bpy.data.materials:
+ if not material.use_nodes:
+ continue
+ bsdf_node = None
+ output_node = None
+ node_tree = material.node_tree
+ links = material.node_tree.links
+ nodes = node_tree.nodes
+ for node in node_tree.nodes:
+ # Check if the node is a BSDF node
+ if node.type == 'BSDF_PRINCIPLED':
+ bsdf_node = node
+ if node.type == 'OUTPUT_MATERIAL':
+ output_node = node
+ if bsdf_node is None or output_node is None:
+ continue
+ #bsdf_node.inputs['Emission'].default_value = 0
+ bsdf_node.inputs['Emission Strength'].default_value = 0
+ mr_node = None
+ bc_node = None
+ for node in node_tree.nodes:
+ # Check if the node is a BSDF node
+ if node.name == 'COMBINE_METALLIC_ROUGHNESS':
+ mr_node = node
+ if node.name == 'COMBINE_BASE_COLOR':
+ bc_node = node
+ if mr_node is None:
+ combine_rgb_node = nodes.new('ShaderNodeCombineColor')
+ #combine_rgb_node.name = 'COMBINE_METALLIC_ROUGHNESS'
+
+ # Optionally, set the RGB values
+ combine_rgb_node.inputs['Red'].default_value = 1.0
+ combine_rgb_node.inputs['Green'].default_value = 0.5
+ combine_rgb_node.inputs['Blue'].default_value = 0.0
+ metallic_input = bsdf_node.inputs["Metallic"]
+
+ if metallic_input.links:
+ source_endpoint = metallic_input.links[0].from_socket
+ links.new(source_endpoint, combine_rgb_node.inputs['Blue'])
+
+ roughness_input = bsdf_node.inputs['Roughness']
+ if roughness_input.links:
+ source_endpoint = roughness_input.links[0].from_socket
+ links.new(source_endpoint, combine_rgb_node.inputs['Green'])
+
+ emission_shader = nodes.new("ShaderNodeEmission")
+ emission_shader.inputs["Strength"].default_value = 1
+ links.new(combine_rgb_node.outputs["Color"], emission_shader.inputs["Color"])
+
+ mix_shader = nodes.new("ShaderNodeMixShader")
+ mix_shader.name = 'COMBINE_METALLIC_ROUGHNESS'
+ links.new(bsdf_node.outputs["BSDF"], mix_shader.inputs[1])
+ links.new(emission_shader.outputs["Emission"], mix_shader.inputs[2])
+ mr_node = mix_shader
+
+ mix_shader_bc = nodes.new("ShaderNodeMixShader")
+ mix_shader_bc.name = 'COMBINE_BASE_COLOR'
+
+ if len(bsdf_node.inputs['Base Color'].links) > 0:
+ socket = bsdf_node.inputs['Base Color'].links[0].from_socket
+ gamma_node = node_tree.nodes.new(type='ShaderNodeGamma')
+
+ gamma_node.inputs[1].default_value = 0.454
+ node_tree.links.new(socket, gamma_node.inputs[0])
+ node_tree.links.new(gamma_node.outputs[0], mix_shader_bc.inputs[1])
+
+ links.new(mix_shader.outputs["Shader"], mix_shader_bc.inputs[2])
+ bc_node = mix_shader_bc
+
+ for l in output_node.inputs['Surface'].links:
+ links.remove(l)
+ links.new(mix_shader_bc.outputs["Shader"], output_node.inputs["Surface"])
+
+ mr_node.inputs["Fac"].default_value = 1.0
+ if render_base_color:
+ bc_node.inputs['Fac'].default_value = 0.0
+ else:
+ bc_node.inputs['Fac'].default_value = 1.0
+
+def switch_to_color_render(output_nodes):
+ bpy.context.scene.view_settings.view_transform = 'Standard'
+ bpy.context.scene.use_nodes = True
+ tree = bpy.context.scene.node_tree
+ links = tree.links
+
+ for i in range(len(output_nodes)):
+ if i + 1 == len(output_nodes):
+ for l in output_nodes[i][1].links:
+ links.remove(l)
+ else:
+ links.new(output_nodes[i][0], output_nodes[i][1])
+
+ for material in bpy.data.materials:
+ if not material.use_nodes:
+ continue
+ node_tree = material.node_tree
+ links = material.node_tree.links
+ nodes = node_tree.nodes
+ mr_node = None
+ bc_node = None
+ for node in node_tree.nodes:
+ if node.name == 'COMBINE_METALLIC_ROUGHNESS':
+ mr_node = node
+ if node.name == 'COMBINE_BASE_COLOR':
+ bc_node = node
+ if mr_node is not None and bc_node is not None:
+ mr_node.inputs["Fac"].default_value = 0.0
+ if len(bc_node.inputs[1].links) > 0:
+ try:
+ node = bc_node.inputs[1].links[0].from_socket.node
+ node.image.colorspace_settings.name = 'sRGB'
+ except:
+ pass
+
+# def ConvertNormalMap(input_exr, output_jpg):
+# import OpenEXR
+# import Imath
+# file = OpenEXR.InputFile(input_exr)
+# channels = file.header()['channels'].keys()
+
+# # Get the image data
+# data_window = file.header()['dataWindow']
+# width = data_window.max.x - data_window.min.x + 1
+# height = data_window.max.y - data_window.min.y + 1
+
+# # Read the X, Y, and Z channels as 32-bit floats
+# x_channel = np.frombuffer(file.channel('X', Imath.PixelType(Imath.PixelType.FLOAT)), dtype=np.float32)
+# y_channel = np.frombuffer(file.channel('Y', Imath.PixelType(Imath.PixelType.FLOAT)), dtype=np.float32)
+# z_channel = np.frombuffer(file.channel('Z', Imath.PixelType(Imath.PixelType.FLOAT)), dtype=np.float32)
+
+# # Reshape the channels into 2D arrays
+# x_channel = x_channel.reshape((height, width))
+# y_channel = y_channel.reshape((height, width))
+# z_channel = z_channel.reshape((height, width))
+
+# # Stack the channels to create a 3D array
+# normal = np.stack((x_channel, y_channel, z_channel), axis=-1)
+# normal = ((normal * 0.5 + 0.5) * 255).astype('uint8')
+# cv2.imwrite(output_jpg, normal)
+
+
+def ConvertNormalMap(input_exr, output_jpg):
+ # Read EXR file with OpenCV (returns float32 image)
+ exr_img = cv2.imread(input_exr, cv2.IMREAD_UNCHANGED)
+ if exr_img is None:
+ raise RuntimeError(f"Failed to load EXR file: {input_exr}")
+ print(f"EXR shape: {exr_img.shape}, dtype: {exr_img.dtype}")
+ normal = ((exr_img * 0.5 + 0.5) * 255).clip(0, 255).astype(np.uint8)
+ cv2.imwrite(output_jpg, normal)
+ print(f"Saved normal map to {output_jpg}")
+
+
+gidx = 0
+def ConvertDepthMap(input_exr, output_png):
+ import bpy
+
+ # cam = bpy.data.objects.get('Camera')
+ cams = [obj for obj in bpy.data.objects if obj.type == 'CAMERA']
+ print("All cameras in scene:")
+ if not cams:
+ raise RuntimeError("No camera objects found in the scene")
+ for c in cams:
+ print(f" {c.name} - type: {c.type}")
+ cam = cams[0]
+
+ print('cam', cam)
+ print('cam.type', cam.type) # should be 'CAMERA'
+ print('cam_data', cam.data) # should not be None
+ print(f"Using camera: {cam.name}")
+
+ cam_data = cam.data
+
+ exr_img = cv2.imread(input_exr, cv2.IMREAD_UNCHANGED)
+ if exr_img is None:
+ raise RuntimeError(f"Failed to load EXR file: {input_exr}")
+
+ print(f"EXR shape: {exr_img.shape}, dtype: {exr_img.dtype}")
+
+ depth_channel = exr_img[:, :, 0] if exr_img.ndim == 3 else exr_img
+
+ # filter
+ depth_channel = depth_channel.copy()
+ depth_channel[depth_channel > 1e9] = 0
+
+ extrinsic_matrix = np.array(cam.matrix_world.copy())
+
+ scene = bpy.context.scene
+ render = scene.render
+ cam_data = cam.data
+
+ resolution_x = render.resolution_x * render.pixel_aspect_x
+ resolution_y = render.resolution_y * render.pixel_aspect_y
+
+ cx = resolution_x / 2.0
+ cy = resolution_y / 2.0
+
+ if cam_data.type == 'ORTHO':
+ aspect_ratio = render.resolution_x / render.resolution_y
+ ortho_scale = cam_data.ortho_scale
+ near = cam_data.clip_start
+ far = cam_data.clip_end
+
+ left = -ortho_scale / 2
+ right = ortho_scale / 2
+ top = (ortho_scale / 2) / aspect_ratio
+ bottom = -top
+
+ proj_matrix = np.array((
+ (2/(right-left), 0, 0, -(right+left)/(right-left)),
+ (0, 2/(top-bottom), 0, -(top+bottom)/(top-bottom)),
+ (0, 0, -2/(far-near), -(far+near)/(far-near)),
+ (0, 0, 0, 1)
+ ))
+ else:
+ if cam_data.sensor_fit == 'VERTICAL':
+ sensor_size = cam_data.sensor_height
+ fit = 'VERTICAL'
+ else:
+ sensor_size = cam_data.sensor_width
+ fit = 'HORIZONTAL'
+
+ focal_length = cam_data.lens
+
+ if fit == 'HORIZONTAL':
+ scale = resolution_x / sensor_size
+ else:
+ scale = resolution_y / sensor_size
+
+ fx = focal_length * scale
+ fy = focal_length * scale
+
+ K = np.array([
+ [fx, 0, cx],
+ [0, fy, cy],
+ [0, 0, 1]
+ ])
+
+ mask = (depth_channel.reshape(-1) == 0)
+ jj, ii = np.meshgrid(np.arange(resolution_x), np.arange(resolution_y))
+ jj = jj + 0.5
+ ii = ii + 0.5
+
+ if cam_data.type == 'ORTHO':
+ cam_pos = np.stack((
+ (jj - cx) * (1.0 / (resolution_x - 1) * ortho_scale),
+ (ii - cy) * (1.0 / (resolution_y - 1) * ortho_scale),
+ depth_channel
+ ), axis=-1)
+ else:
+ image_pos = np.stack((jj * depth_channel, ii * depth_channel, depth_channel), axis=-1)
+ cam_pos = image_pos @ np.linalg.inv(K).T
+
+ cam_pos[..., 1:] = -cam_pos[..., 1:]
+
+ world_pos = cam_pos @ extrinsic_matrix[:3, :3].T + extrinsic_matrix[:3, 3].reshape(1, 1, 3)
+ world_pos = world_pos.reshape(-1, 3)
+ world_pos[mask] = 0
+ world_pos = world_pos.reshape(cam_pos.shape)
+ world_pos = np.stack((world_pos[..., 0], world_pos[..., 2], -world_pos[..., 1]), axis=-1)
+
+ img_out = np.clip((0.5 + world_pos) * 255, 0, 255).astype('uint8')
+ cv2.imwrite(output_png, img_out)
+ print(f"Saved depth map to {output_png}")
+
+
+def init_render(engine='CYCLES', resolution=512, geo_mode=False):
+ bpy.context.scene.render.engine = engine
+ bpy.context.scene.render.resolution_x = resolution
+ bpy.context.scene.render.resolution_y = resolution
+ bpy.context.scene.render.resolution_percentage = 100
+ bpy.context.scene.render.image_settings.file_format = 'PNG'
+ bpy.context.scene.render.image_settings.color_mode = 'RGBA'
+ bpy.context.scene.render.film_transparent = True
+
+ bpy.context.scene.cycles.device = 'GPU'
+ #bpy.context.scene.cycles.samples = 128 if not geo_mode else 1
+ bpy.context.scene.cycles.filter_type = 'BOX'
+ bpy.context.scene.cycles.filter_width = 1
+ bpy.context.scene.cycles.diffuse_bounces = 1
+ bpy.context.scene.cycles.glossy_bounces = 1
+ # bpy.context.scene.cycles.transparent_max_bounces = 3 if not geo_mode else 0
+ # bpy.context.scene.cycles.transmission_bounces = 3 if not geo_mode else 1
+ bpy.context.scene.cycles.use_denoising = True
+
+ bpy.context.preferences.addons['cycles'].preferences.get_devices()
+ # bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'CUDA'
+
+def init_nodes(save_depth=False, save_normal=False, save_albedo=False, save_mr = False, save_mist=False):
+ if not any([save_depth, save_normal, save_albedo, save_mist]):
+ return {}, {}, []
+ outputs = {}
+ spec_nodes = {}
+ composite_nodes = []
+ bpy.context.scene.use_nodes = True
+ bpy.context.scene.view_layers['ViewLayer'].use_pass_z = save_depth
+ bpy.context.scene.view_layers['ViewLayer'].use_pass_normal = save_normal
+ bpy.context.scene.view_layers['ViewLayer'].use_pass_diffuse_color = save_albedo
+ bpy.context.scene.view_layers['ViewLayer'].use_pass_mist = save_mist
+
+ nodes = bpy.context.scene.node_tree.nodes
+ links = bpy.context.scene.node_tree.links
+ for n in nodes:
+ nodes.remove(n)
+
+ render_layers = nodes.new('CompositorNodeRLayers')
+
+ if save_depth:
+ depth_file_output = nodes.new('CompositorNodeOutputFile')
+ depth_file_output.base_path = ''
+ depth_file_output.file_slots[0].use_node_format = True
+ depth_file_output.format.file_format = "OPEN_EXR"
+ links.new(render_layers.outputs['Depth'], depth_file_output.inputs[0])
+
+ outputs['depth'] = depth_file_output
+ composite_nodes.append((render_layers.outputs['Depth'], depth_file_output.inputs[0]))
+
+ if save_normal:
+ normal_file_output = nodes.new('CompositorNodeOutputFile')
+ normal_file_output.base_path = ''
+ normal_file_output.file_slots[0].use_node_format = True
+ normal_file_output.format.file_format = 'OPEN_EXR'
+ links.new(render_layers.outputs['Normal'], normal_file_output.inputs[0])
+
+ outputs['normal'] = normal_file_output
+ composite_nodes.append((render_layers.outputs['Normal'], normal_file_output.inputs[0]))
+
+ if save_albedo:
+ albedo_file_output = nodes.new('CompositorNodeOutputFile')
+ albedo_file_output.base_path = ''
+ albedo_file_output.file_slots[0].use_node_format = True
+ albedo_file_output.format.file_format = 'PNG'
+ albedo_file_output.format.color_mode = 'RGBA'
+ albedo_file_output.format.color_depth = '8'
+
+ alpha_albedo = nodes.new('CompositorNodeSetAlpha')
+
+ links.new(render_layers.outputs['DiffCol'], alpha_albedo.inputs['Image'])
+ links.new(render_layers.outputs['Alpha'], alpha_albedo.inputs['Alpha'])
+ links.new(alpha_albedo.outputs['Image'], albedo_file_output.inputs[0])
+
+ outputs['albedo'] = albedo_file_output
+ #composite_nodes.append((alpha_albedo.outputs['Image'], albedo_file_output.inputs[0]))
+
+ if save_mr:
+ mr_file_output = tree.nodes.new(type='CompositorNodeOutputFile')
+ mr_file_output.base_path = ''
+ mr_file_output.file_slots[0].use_node_format = True
+ mr_file_output.format.file_format = 'OPEN_EXR'
+
+ links.new(render_layers.outputs['Image'], mr_file_output.inputs[0])
+
+ outputs['mr'] = mr_file_output
+ composite_nodes.append((render_layers.outputs['Image'], mr_file_output.inputs[0]))
+
+ if save_mist:
+ bpy.data.worlds['World'].mist_settings.start = 0
+ bpy.data.worlds['World'].mist_settings.depth = 10
+
+ mist_file_output = nodes.new('CompositorNodeOutputFile')
+ mist_file_output.base_path = ''
+ mist_file_output.file_slots[0].use_node_format = True
+ mist_file_output.format.file_format = 'PNG'
+ mist_file_output.format.color_mode = 'BW'
+ mist_file_output.format.color_depth = '16'
+
+ links.new(render_layers.outputs['Mist'], mist_file_output.inputs[0])
+
+ outputs['mist'] = mist_file_output
+ composite_nodes.append((render_layers.outputs['Mist'], mist_file_output.inputs[0]))
+
+ return outputs, spec_nodes, composite_nodes
+
+def init_scene() -> None:
+ """Resets the scene to a clean state.
+
+ Returns:
+ None
+ """
+ # delete everything
+ for obj in bpy.data.objects:
+ bpy.data.objects.remove(obj, do_unlink=True)
+
+ # delete all the materials
+ for material in bpy.data.materials:
+ bpy.data.materials.remove(material, do_unlink=True)
+
+ # delete all the textures
+ for texture in bpy.data.textures:
+ bpy.data.textures.remove(texture, do_unlink=True)
+
+ # delete all the images
+ for image in bpy.data.images:
+ bpy.data.images.remove(image, do_unlink=True)
+
+def init_camera():
+ cam = bpy.data.objects.new('Camera', bpy.data.cameras.new('Camera'))
+ bpy.context.collection.objects.link(cam)
+ bpy.context.scene.camera = cam
+ cam.data.sensor_height = cam.data.sensor_width = 32
+ cam_constraint = cam.constraints.new(type='TRACK_TO')
+ cam_constraint.track_axis = 'TRACK_NEGATIVE_Z'
+ cam_constraint.up_axis = 'UP_Y'
+ cam_empty = bpy.data.objects.new("Empty", None)
+ cam_empty.location = (0, 0, 0)
+ bpy.context.scene.collection.objects.link(cam_empty)
+ cam_constraint.target = cam_empty
+ return cam
+
+def init_lighting():
+ # Clear existing lights
+ bpy.ops.object.select_all(action="DESELECT")
+ bpy.ops.object.select_by_type(type="LIGHT")
+ bpy.ops.object.delete()
+
+ # Create key light
+ default_light = bpy.data.objects.new("Default_Light", bpy.data.lights.new("Default_Light", type="POINT"))
+ bpy.context.collection.objects.link(default_light)
+ default_light.data.energy = 1000
+ default_light.location = (4, 1, 6)
+ default_light.rotation_euler = (0, 0, 0)
+
+ # create top light
+ top_light = bpy.data.objects.new("Top_Light", bpy.data.lights.new("Top_Light", type="AREA"))
+ bpy.context.collection.objects.link(top_light)
+ top_light.data.energy = 10000
+ top_light.location = (0, 0, 10)
+ top_light.scale = (100, 100, 100)
+
+ # create bottom light
+ bottom_light = bpy.data.objects.new("Bottom_Light", bpy.data.lights.new("Bottom_Light", type="AREA"))
+ bpy.context.collection.objects.link(bottom_light)
+ bottom_light.data.energy = 1000
+ bottom_light.location = (0, 0, -10)
+ bottom_light.rotation_euler = (0, 0, 0)
+
+ return {
+ "default_light": default_light,
+ "top_light": top_light,
+ "bottom_light": bottom_light
+ }
+
+
+def load_object(object_path: str) -> None:
+ """Loads a model with a supported file extension into the scene.
+
+ Args:
+ object_path (str): Path to the model file.
+
+ Raises:
+ ValueError: If the file extension is not supported.
+
+ Returns:
+ None
+ """
+ file_extension = object_path.split(".")[-1].lower()
+ if file_extension is None:
+ raise ValueError(f"Unsupported file type: {object_path}")
+
+ if file_extension == "usdz":
+ # install usdz io package
+ dirname = os.path.dirname(os.path.realpath(__file__))
+ usdz_package = os.path.join(dirname, "io_scene_usdz.zip")
+ bpy.ops.preferences.addon_install(filepath=usdz_package)
+ # enable it
+ addon_name = "io_scene_usdz"
+ bpy.ops.preferences.addon_enable(module=addon_name)
+ # import the usdz
+ from io_scene_usdz.import_usdz import import_usdz
+
+ import_usdz(context, filepath=object_path, materials=True, animations=True)
+ return None
+
+ # load from existing import functions
+ import_function = IMPORT_FUNCTIONS[file_extension]
+
+ print(f"Loading object from {object_path}")
+ if file_extension == "blend":
+ import_function(directory=object_path, link=False)
+ elif file_extension in {"glb", "gltf"}:
+ import_function(filepath=object_path, merge_vertices=True, import_shading='NORMALS')
+ else:
+ import_function(filepath=object_path)
+
+def delete_invisible_objects() -> None:
+ """Deletes all invisible objects in the scene.
+
+ Returns:
+ None
+ """
+ # bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.object.select_all(action="DESELECT")
+ for obj in bpy.context.scene.objects:
+ if obj.hide_viewport or obj.hide_render:
+ obj.hide_viewport = False
+ obj.hide_render = False
+ obj.hide_select = False
+ obj.select_set(True)
+ bpy.ops.object.delete()
+
+ # Delete invisible collections
+ invisible_collections = [col for col in bpy.data.collections if col.hide_viewport]
+ for col in invisible_collections:
+ bpy.data.collections.remove(col)
+
+def split_mesh_normal():
+ bpy.ops.object.select_all(action="DESELECT")
+ objs = [obj for obj in bpy.context.scene.objects if obj.type == "MESH"]
+ bpy.context.view_layer.objects.active = objs[0]
+ for obj in objs:
+ obj.select_set(True)
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.split_normals()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.select_all(action="DESELECT")
+
+def delete_custom_normals():
+ for this_obj in bpy.data.objects:
+ if this_obj.type == "MESH":
+ bpy.context.view_layer.objects.active = this_obj
+ bpy.ops.mesh.customdata_custom_splitnormals_clear()
+
+def override_material():
+ new_mat = bpy.data.materials.new(name="Override0123456789")
+ new_mat.use_nodes = True
+ new_mat.node_tree.nodes.clear()
+ bsdf = new_mat.node_tree.nodes.new('ShaderNodeBsdfDiffuse')
+ bsdf.inputs[0].default_value = (0.5, 0.5, 0.5, 1)
+ bsdf.inputs[1].default_value = 1
+ output = new_mat.node_tree.nodes.new('ShaderNodeOutputMaterial')
+ new_mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
+ bpy.context.scene.view_layers['ViewLayer'].material_override = new_mat
+
+def unhide_all_objects() -> None:
+ """Unhides all objects in the scene.
+
+ Returns:
+ None
+ """
+ for obj in bpy.context.scene.objects:
+ obj.hide_set(False)
+
+def convert_to_meshes() -> None:
+ """Converts all objects in the scene to meshes.
+
+ Returns:
+ None
+ """
+ bpy.ops.object.select_all(action="DESELECT")
+ bpy.context.view_layer.objects.active = [obj for obj in bpy.context.scene.objects if obj.type == "MESH"][0]
+ for obj in bpy.context.scene.objects:
+ obj.select_set(True)
+ bpy.ops.object.convert(target="MESH")
+
+def triangulate_meshes() -> None:
+ """Triangulates all meshes in the scene.
+
+ Returns:
+ None
+ """
+ bpy.ops.object.select_all(action="DESELECT")
+ objs = [obj for obj in bpy.context.scene.objects if obj.type == "MESH"]
+ bpy.context.view_layer.objects.active = objs[0]
+ for obj in objs:
+ obj.select_set(True)
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.reveal()
+ bpy.ops.mesh.select_all(action="SELECT")
+ bpy.ops.mesh.quads_convert_to_tris(quad_method="BEAUTY", ngon_method="BEAUTY")
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.object.select_all(action="DESELECT")
+
+def scene_bbox() -> Tuple[Vector, Vector]:
+ """Returns the bounding box of the scene.
+
+ Taken from Shap-E rendering script
+ (https://github.com/openai/shap-e/blob/main/shap_e/rendering/blender/blender_script.py#L68-L82)
+
+ Returns:
+ Tuple[Vector, Vector]: The minimum and maximum coordinates of the bounding box.
+ """
+ bbox_min = (math.inf,) * 3
+ bbox_max = (-math.inf,) * 3
+ found = False
+ scene_meshes = [obj for obj in bpy.context.scene.objects.values() if isinstance(obj.data, bpy.types.Mesh)]
+ for obj in scene_meshes:
+ found = True
+ for coord in obj.bound_box:
+ coord = Vector(coord)
+ coord = obj.matrix_world @ coord
+ bbox_min = tuple(min(x, y) for x, y in zip(bbox_min, coord))
+ bbox_max = tuple(max(x, y) for x, y in zip(bbox_max, coord))
+ if not found:
+ raise RuntimeError("no objects in scene to compute bounding box for")
+ return Vector(bbox_min), Vector(bbox_max)
+
+def normalize_scene() -> Tuple[float, Vector]:
+ """Normalizes the scene by scaling and translating it to fit in a unit cube centered
+ at the origin.
+
+ Mostly taken from the Point-E / Shap-E rendering script
+ (https://github.com/openai/point-e/blob/main/point_e/evals/scripts/blender_script.py#L97-L112),
+ but fix for multiple root objects: (see bug report here:
+ https://github.com/openai/shap-e/pull/60).
+
+ Returns:
+ Tuple[float, Vector]: The scale factor and the offset applied to the scene.
+ """
+ scene_root_objects = [obj for obj in bpy.context.scene.objects.values() if not obj.parent]
+ if len(scene_root_objects) > 1:
+ # create an empty object to be used as a parent for all root objects
+ scene = bpy.data.objects.new("ParentEmpty", None)
+ bpy.context.scene.collection.objects.link(scene)
+
+ # parent all root objects to the empty object
+ for obj in scene_root_objects:
+ obj.parent = scene
+ else:
+ scene = scene_root_objects[0]
+
+ bbox_min, bbox_max = scene_bbox()
+ scale = 1 / max(bbox_max - bbox_min)
+ scene.scale = scene.scale * scale
+
+ # Apply scale to matrix_world.
+ bpy.context.view_layer.update()
+ bbox_min, bbox_max = scene_bbox()
+ offset = -(bbox_min + bbox_max) / 2
+ scene.matrix_world.translation += offset
+ bpy.ops.object.select_all(action="DESELECT")
+
+ return scale, offset
+
+def get_transform_matrix(obj: bpy.types.Object) -> list:
+ pos, rt, _ = obj.matrix_world.decompose()
+ rt = rt.to_matrix()
+ matrix = []
+ for ii in range(3):
+ a = []
+ for jj in range(3):
+ a.append(rt[ii][jj])
+ a.append(pos[ii])
+ matrix.append(a)
+ matrix.append([0, 0, 0, 1])
+ return matrix
+
+
+def main(arg):
+ os.makedirs(arg.output_folder, exist_ok=True)
+
+ if arg.geo_mode:
+ views = trellis_cond_camera_sequence(arg.views)
+ arg.save_mesh = True
+ else:
+ views = orthogonal_camera_sequence()
+ arg.save_albedo = True
+ arg.save_mr = True
+ arg.save_normal = True
+ arg.save_depth = True
+ arg.save_mesh = False
+
+ # Initialize context
+ init_render(engine=arg.engine, resolution=arg.resolution, geo_mode=arg.geo_mode)
+ outputs, spec_nodes, composite_nodes = init_nodes(
+ save_depth=arg.save_depth,
+ save_normal=arg.save_normal,
+ save_albedo=arg.save_albedo,
+ save_mist=arg.save_mist
+ )
+ if arg.object.endswith(".blend"):
+ delete_invisible_objects()
+ else:
+ init_scene()
+ load_object(arg.object)
+ if arg.split_normal:
+ split_mesh_normal()
+ # delete_custom_normals()
+ print('[INFO] Scene initialized.')
+
+ # normalize scene
+ scale, offset = normalize_scene()
+ print('[INFO] Scene normalized.')
+
+ # Initialize camera and lighting
+ cam = init_camera()
+ init_lighting()
+ print('[INFO] Camera and lighting initialized.')
+
+ # Override material
+ #if arg.geo_mode:
+ # override_material()
+
+ # Create a list of views
+ to_export = {
+ "aabb": [[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]],
+ "scale": scale,
+ "offset": [offset.x, offset.y, offset.z],
+ "frames": []
+ }
+
+ for i, view in enumerate(views):
+ cam.location = (
+ view['cam_dis'] * np.cos(view['hangle']) * np.cos(view['vangle']),
+ view['cam_dis'] * np.sin(view['hangle']) * np.cos(view['vangle']),
+ view['cam_dis'] * np.sin(view['vangle'])
+ )
+ cam.data.lens = 16 / np.tan(view['fov'] / 2)
+
+ if view['proj_type'] == 1:
+ cam.data.type = "ORTHO"
+ cam.data.ortho_scale = 1.2
+
+ bpy.context.scene.render.filepath = os.path.join(arg.output_folder, f'{i:03d}.png')
+ for name, output in outputs.items():
+ output.file_slots[0].path = os.path.join(arg.output_folder, f'{i:03d}_{name}')
+
+ # Render the scene
+ if not arg.geo_mode:
+ switch_to_mr_render(False, composite_nodes)
+ bpy.ops.render.render(write_still=True)
+ shutil.copyfile(bpy.context.scene.render.filepath,
+ bpy.context.scene.render.filepath.replace('.png', '_mr.png'))
+ switch_to_color_render(composite_nodes)
+
+ bpy.ops.render.render(write_still=True)
+ bpy.context.view_layer.update()
+ for name, output in outputs.items():
+ ext = EXT[output.format.file_format]
+ path = glob.glob(f'{output.file_slots[0].path}*.{ext}')[0]
+ os.rename(path, f'{output.file_slots[0].path}.{ext}')
+
+ if not arg.geo_mode:
+ ConvertNormalMap(os.path.join(arg.output_folder, f'{i:03d}_normal.exr'),
+ os.path.join(arg.output_folder, f'{i:03d}_normal.jpg'))
+ ConvertDepthMap(os.path.join(arg.output_folder, f'{i:03d}_depth.exr'),
+ os.path.join(arg.output_folder, f'{i:03d}_pos.jpg'))
+ os.remove(os.path.join(arg.output_folder, f'{i:03d}_normal.exr'))
+ os.remove(os.path.join(arg.output_folder, f'{i:03d}_depth.exr'))
+
+ # Save camera parameters
+ metadata = {
+ "file_path": f'{i:03d}.png',
+ "camera_angle_x": view['fov'],
+ 'proj_type': view['proj_type'],
+ 'azimuth': view['hangle'],
+ 'elevation': view['vangle'],
+ 'cam_dis': view['cam_dis'],
+ "transform_matrix": get_transform_matrix(cam)
+ }
+ to_export["frames"].append(metadata)
+
+ # Save the camera parameters
+ transform_path = os.path.join(arg.output_folder, 'transforms.json')
+ with open(transform_path, 'w') as f:
+ json.dump(to_export, f, indent=4)
+
+ if arg.save_mesh:
+ # triangulate meshes
+ unhide_all_objects()
+ convert_to_meshes()
+ triangulate_meshes()
+ print('[INFO] Meshes triangulated.')
+
+ # export ply mesh
+ bpy.ops.wm.ply_export(filepath=os.path.join(arg.output_folder, 'mesh.ply'),
+ export_triangulated_mesh=True, up_axis='Y',
+ forward_axis='NEGATIVE_Z')
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Renders given obj file by rotation a camera around it.')
+ parser.add_argument('--views', type=int, default=24,
+ help='JSON string of views. Contains a list of {yaw, pitch, radius, fov} object.')
+ parser.add_argument('--object', type=str,
+ help='Path to the 3D model file to be rendered.')
+ parser.add_argument('--output_folder', type=str, default='/tmp',
+ help='The path the output will be dumped to.')
+ parser.add_argument('--resolution', type=int, default=512,
+ help='Resolution of the images.')
+ parser.add_argument('--engine', type=str, default='CYCLES',
+ help='Blender internal engine for rendering. E.g. CYCLES, BLENDER_EEVEE, ...')
+ parser.add_argument('--geo_mode', action='store_true',
+ help='Geometry mode for rendering.')
+ parser.add_argument('--save_depth', action='store_true',
+ help='Save the depth maps.')
+ parser.add_argument('--save_normal', action='store_true',
+ help='Save the normal maps.')
+ parser.add_argument('--save_albedo', action='store_true',
+ help='Save the albedo maps.')
+ parser.add_argument('--save_mr', action='store_true',
+ help='Save the MR maps.')
+ parser.add_argument('--save_mist', action='store_true',
+ help='Save the mist distance maps.')
+ parser.add_argument('--split_normal', action='store_true',
+ help='Split the normals of the mesh.')
+ parser.add_argument('--save_mesh', action='store_true',
+ help='Save the mesh as a .ply file.')
+ argv = sys.argv[sys.argv.index("--") + 1:]
+ args = parser.parse_args(argv)
+
+ main(args)
diff --git a/Hunyuan3D-2.1/hy3dshape/tools/watertight/watertight_and_sample.py b/Hunyuan3D-2.1/hy3dshape/tools/watertight/watertight_and_sample.py
new file mode 100644
index 0000000000000000000000000000000000000000..9a1e684774db475931af9078a3cb153d935834c7
--- /dev/null
+++ b/Hunyuan3D-2.1/hy3dshape/tools/watertight/watertight_and_sample.py
@@ -0,0 +1,223 @@
+# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
+# except for the third-party components listed below.
+# Hunyuan 3D does not impose any additional limitations beyond what is outlined
+# in the repsective licenses of these third-party components.
+# Users must comply with all terms and conditions of original licenses of these third-party
+# components and must ensure that the usage of the third party components adheres to
+# all relevant laws and regulations.
+
+# For avoidance of doubts, Hunyuan 3D means the large language models and
+# their software and algorithms, including trained model weights, parameters (including
+# optimizer states), machine-learning model code, inference-enabling code, training-enabling code,
+# fine-tuning enabling code and other elements of the foregoing made publicly available
+# by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
+
+import argparse
+import igl
+import numpy as np
+import os
+from scipy.stats import truncnorm
+import trimesh
+
+def random_sample_pointcloud(mesh, num = 30000):
+ points, face_idx = mesh.sample(num, return_index=True)
+ normals = mesh.face_normals[face_idx]
+ rng = np.random.default_rng()
+ index = rng.choice(num, num, replace=False)
+ return points[index], normals[index]
+
+def sharp_sample_pointcloud(mesh, num=16384):
+ V = mesh.vertices
+ N = mesh.face_normals
+ VN = mesh.vertex_normals
+ F = mesh.faces
+ VN2 = np.ones(V.shape[0])
+ for i in range(3):
+ dot = np.stack((VN2[F[:,i]], np.sum(VN[F[:,i]] * N, axis=-1)), axis=-1)
+ VN2[F[:,i]] = np.min(dot, axis=-1)
+
+ sharp_mask = VN2<0.985
+ # collect edge
+ edge_a = np.concatenate((F[:,0],F[:,1],F[:,2]))
+ edge_b = np.concatenate((F[:,1],F[:,2],F[:,0]))
+ sharp_edge = ((sharp_mask[edge_a] * sharp_mask[edge_b]))
+ edge_a = edge_a[sharp_edge>0]
+ edge_b = edge_b[sharp_edge>0]
+
+ sharp_verts_a = V[edge_a]
+ sharp_verts_b = V[edge_b]
+ sharp_verts_an = VN[edge_a]
+ sharp_verts_bn = VN[edge_b]
+
+ weights = np.linalg.norm(sharp_verts_b - sharp_verts_a, axis=-1)
+ weights /= np.sum(weights)
+
+ random_number = np.random.rand(num)
+ w = np.random.rand(num,1)
+ index = np.searchsorted(weights.cumsum(), random_number)
+ samples = w * sharp_verts_a[index] + (1 - w) * sharp_verts_b[index]
+ normals = w * sharp_verts_an[index] + (1 - w) * sharp_verts_bn[index]
+ return samples, normals
+
+def sample_sdf(mesh, random_surface, sharp_surface):
+ n_volume_points = sharp_surface.shape[0] * 2
+ vol_points = (np.random.rand(n_volume_points, 3) - 0.5) * 2 * 1.05
+
+ a, b = -0.25, 0.25
+ mu = 0
+
+ # get near points (add offset on surface points)
+ offset1 = truncnorm.rvs((a - mu) / 0.005, (b - mu) / 0.005, loc=mu, scale=0.005, size=(len(random_surface), 3))
+ offset2 = truncnorm.rvs((a - mu) / 0.05, (b - mu) / 0.05, loc=mu, scale=0.05, size=(len(random_surface), 3))
+ random_near_points = np.concatenate([
+ random_surface + offset1,
+ random_surface + offset2
+ ], axis=0)
+
+ unit_num = len(sharp_surface) // 6
+ sharp_near_points = np.concatenate([
+ sharp_surface[:unit_num] + np.random.normal(scale=0.001, size=(unit_num, 3)),
+ sharp_surface[unit_num:unit_num*2] + np.random.normal(scale=0.003, size=(unit_num,3)),
+ sharp_surface[unit_num*2:unit_num*3] + np.random.normal(scale=0.06, size=(unit_num,3)),
+ sharp_surface[unit_num*3:unit_num*4] + np.random.normal(scale=0.01, size=(unit_num,3)),
+ sharp_surface[unit_num*4:unit_num*5] + np.random.normal(scale=0.02, size=(unit_num,3)),
+ sharp_surface[unit_num*5:] + np.random.normal(scale=0.04, size=(len(sharp_surface)-5*unit_num,3))
+ ], axis=0)
+
+ np.random.shuffle(random_near_points)
+ np.random.shuffle(sharp_near_points)
+
+ sign_type = igl.SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER
+ try:
+ vol_sdf, I, C = igl.signed_distance(
+ vol_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False,
+ sign_type=sign_type)
+ except:
+ vol_sdf, I, C = igl.signed_distance(
+ vol_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False)
+ try:
+ random_near_sdf, I, C = igl.signed_distance(
+ random_near_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False,
+ sign_type=sign_type)
+ except:
+ random_near_sdf, I, C = igl.signed_distance(
+ random_near_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False)
+ try:
+ sharp_near_sdf, I, C = igl.signed_distance(
+ sharp_near_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False,
+ sign_type=sign_type)
+ except:
+ sharp_near_sdf, I, C = igl.signed_distance(
+ sharp_near_points.astype(np.float32),
+ mesh.vertices, mesh.faces,
+ return_normals=False)
+
+ vol_label = -vol_sdf
+ random_near_label = -random_near_sdf
+ sharp_near_label = -sharp_near_sdf
+
+ data = {
+ "vol_points": vol_points.astype(np.float16),
+ "vol_label": vol_label.astype(np.float16),
+ "random_near_points": random_near_points.astype(np.float16),
+ "random_near_label": random_near_label.astype(np.float16),
+ "sharp_near_points": sharp_near_points.astype(np.float16),
+ "sharp_near_label": sharp_near_label.astype(np.float16)
+ }
+ return data
+
+def SampleMesh(V, F):
+ mesh = trimesh.Trimesh(vertices=V, faces=F)
+
+ area = mesh.area
+ sample_num = 499712//4
+
+ random_surface, random_normal = random_sample_pointcloud(mesh, num=sample_num)
+ random_sharp_surface, sharp_normal = sharp_sample_pointcloud(mesh, num=sample_num)
+
+ #save_surface
+ surface = np.concatenate((random_surface, random_normal), axis = 1).astype(np.float16)
+ sharp_surface = np.concatenate((random_sharp_surface, sharp_normal), axis=1).astype(np.float16)
+
+ surface_data = {
+ "random_surface": surface,
+ "sharp_surface": sharp_surface,
+ }
+
+ sdf_data = sample_sdf(mesh, random_surface, random_sharp_surface)
+ return surface_data, sdf_data
+
+def normalize_to_unit_box(V):
+ """
+ Normalize the vertices V to fit inside a unit bounding box [0,1]^3.
+ V: (n,3) numpy array of vertex positions.
+ Returns: normalized V
+ """
+ V_min = V.min(axis=0)
+ V_max = V.max(axis=0)
+ scale = (V_max - V_min).max() * 1.01
+ V_normalized = (V - V_min) / scale
+ return V_normalized
+
+# Given: V (n x 3 array of vertices), F (m x 3 array of faces)
+# Parameters epsilon/grid_res
+def Watertight(V, F, epsilon = 2.0/256, grid_res = 256):
+ # Compute bounding box
+ min_corner = V.min(axis=0)
+ max_corner = V.max(axis=0)
+ padding = 0.05 * (max_corner - min_corner)
+ min_corner -= padding
+ max_corner += padding
+
+ # Create a uniform grid
+ x = np.linspace(min_corner[0], max_corner[0], grid_res)
+ y = np.linspace(min_corner[1], max_corner[1], grid_res)
+ z = np.linspace(min_corner[2], max_corner[2], grid_res)
+ X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
+ grid_points = np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T
+
+ # Compute SDF at grid points using igl.signed_distance with pseudo normals
+ sdf, _, _ = igl.signed_distance(
+ grid_points, V, F, sign_type=igl.SIGNED_DISTANCE_TYPE_PSEUDONORMAL
+ )
+
+ # igl.marching_cubes returns (vertices, faces)
+ mc_verts, mc_faces = igl.marching_cubes(epsilon - np.abs(sdf), grid_points, grid_res, grid_res, grid_res, 0.0)
+
+ # mc_verts: (k x 3) array of vertices of the epsilon contour
+ # mc_faces: (l x 3) array of faces of the epsilon contour
+ return mc_verts, mc_faces
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Process an OBJ file and output surface and SDF data.')
+ parser.add_argument('--input_obj', type=str, help='Path to the input OBJ file')
+ parser.add_argument('--output_prefix', type=str, default=None,
+ help='Base name for output files (default: input OBJ filename without extension)')
+ args = parser.parse_args()
+
+ input_obj = args.input_obj
+ name = args.output_prefix
+
+ V, F = igl.read_triangle_mesh(input_obj)
+ V = normalize_to_unit_box(V)
+
+ mc_verts, mc_faces = Watertight(V, F)
+ surface_data, sdf_data = SampleMesh(mc_verts, mc_faces)
+
+ parent_folder = os.path.dirname(args.output_prefix)
+ os.makedirs(parent_folder, exist_ok=True)
+ export_surface = f'{name}_surface.npz'
+ np.savez(export_surface, **surface_data)
+ export_sdf = f'{name}_sdf.npz'
+ np.savez(export_sdf, **sdf_data)
+ igl.write_obj(f'{name}_watertight.obj', mc_verts, mc_faces)
diff --git a/Hunyuan3D-2.1/requirements.txt b/Hunyuan3D-2.1/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7225d5d78602440a75a790991d07dc1332fcac2d
--- /dev/null
+++ b/Hunyuan3D-2.1/requirements.txt
@@ -0,0 +1,70 @@
+--extra-index-url https://download.blender.org/pypi/
+
+# Build Tools
+ninja==1.11.1.1
+pybind11==2.13.4
+
+# Core ML/Deep Learning
+transformers==4.46.0
+diffusers==0.30.0
+accelerate==1.1.1
+pytorch-lightning==1.9.5
+huggingface-hub==0.30.2
+safetensors==0.4.4
+
+# Scientific Computing
+numpy==1.24.4
+scipy==1.14.1
+einops==0.8.0
+pandas==2.2.2
+
+# Computer Vision & Image Processing
+opencv-python==4.10.0.84
+imageio==2.36.0
+scikit-image==0.24.0
+rembg==2.0.65
+realesrgan==0.3.0
+tb_nightly==2.18.0a20240726
+basicsr==1.4.2
+
+# 3D Mesh Processing
+trimesh==4.4.7
+pymeshlab==2022.2.post3
+pygltflib==1.16.3
+xatlas==0.0.9
+open3d==0.18.0
+
+# Configuration Management
+omegaconf==2.3.0
+pyyaml==6.0.2
+configargparse==1.7
+
+# Web Framework (for demo)
+gradio==5.33.0
+fastapi==0.115.12
+uvicorn==0.34.3
+
+# Utilities
+tqdm==4.66.5
+psutil==6.0.0
+
+# GPU Computing (requires CUDA)
+cupy-cuda12x==13.4.1
+
+# Blender
+bpy==4.0
+
+# ONNX Runtime
+onnxruntime==1.16.3
+torchmetrics==1.6.0
+
+timm
+pythreejs
+
+# torchdiffeq
+# deepspeed
+# torch_cluster
+
+pydantic==2.10.6
+
+
diff --git a/Hunyuan3D-2.1/torchvision_fix.py b/Hunyuan3D-2.1/torchvision_fix.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ea6fb43fb61e3d1f201f78dfe0ef2a25a44b4e8
--- /dev/null
+++ b/Hunyuan3D-2.1/torchvision_fix.py
@@ -0,0 +1,104 @@
+# Torchvision compatibility fix for functional_tensor module
+# This file helps resolve compatibility issues between different torchvision versions
+
+import sys
+import torchvision
+
+def fix_torchvision_functional_tensor():
+ """
+ Fix torchvision.transforms.functional_tensor import issue
+ """
+ try:
+ # Check if the module exists in the expected location
+ import torchvision.transforms.functional_tensor
+ print("torchvision.transforms.functional_tensor is available")
+ return True
+ except ImportError:
+ print("torchvision.transforms.functional_tensor not found, applying compatibility fix...")
+
+ try:
+ # Create a mock functional_tensor module with the required functions
+ import torch
+ import torchvision.transforms.functional as F
+
+ class FunctionalTensorMock:
+ """Mock module to replace functional_tensor"""
+
+ @staticmethod
+ def rgb_to_grayscale(img, num_output_channels=1):
+ """Convert RGB image to grayscale"""
+ if hasattr(F, 'rgb_to_grayscale'):
+ return F.rgb_to_grayscale(img, num_output_channels)
+ else:
+ # Fallback implementation
+ if len(img.shape) == 4: # Batch of images
+ weights = torch.tensor([0.299, 0.587, 0.114],
+ device=img.device, dtype=img.dtype).view(1, 3, 1, 1)
+ else: # Single image
+ weights = torch.tensor([0.299, 0.587, 0.114],
+ device=img.device, dtype=img.dtype).view(3, 1, 1)
+
+ grayscale = torch.sum(img * weights, dim=-3, keepdim=True)
+
+ if num_output_channels == 3:
+ if len(img.shape) == 4:
+ grayscale = grayscale.repeat(1, 3, 1, 1)
+ else:
+ grayscale = grayscale.repeat(3, 1, 1)
+
+ return grayscale
+
+ @staticmethod
+ def resize(img, size, interpolation=2, antialias=None):
+ """Resize function wrapper"""
+ try:
+ from torchvision.transforms.v2.functional import resize as v2_resize
+ return v2_resize(img, size,
+ interpolation=interpolation,
+ antialias=antialias)
+ except ImportError:
+ if hasattr(F, 'resize'):
+ return F.resize(img, size, interpolation=interpolation)
+ else:
+ import torch.nn.functional as torch_F
+ if isinstance(size, int):
+ size = (size, size)
+ return torch_F.interpolate(
+ img.unsqueeze(0) if len(img.shape) == 3 else img,
+ size=size, mode='bilinear', align_corners=False)
+
+ def __getattr__(self, name):
+ """Fallback to regular functional module"""
+ if hasattr(F, name):
+ return getattr(F, name)
+ else:
+ # Try v2.functional
+ try:
+ import torchvision.transforms.v2.functional as v2_F
+ if hasattr(v2_F, name):
+ return getattr(v2_F, name)
+ except ImportError:
+ pass
+
+ raise AttributeError(f"'{name}' not found in functional_tensor mock")
+
+ # Create the mock module instance
+ functional_tensor_mock = FunctionalTensorMock()
+
+ # Monkey patch the old location
+ sys.modules['torchvision.transforms.functional_tensor'] = functional_tensor_mock
+ print("Applied compatibility fix: created functional_tensor mock module")
+ return True
+
+ except Exception as e:
+ print(f"Failed to create functional_tensor mock: {e}")
+ return False
+
+def apply_fix():
+ """Apply the torchvision compatibility fix"""
+ print(f"Torchvision version: {torchvision.__version__}")
+ return fix_torchvision_functional_tensor()
+
+if __name__ == "__main__":
+ apply_fix()
+
\ No newline at end of file
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 0000000000000000000000000000000000000000..8b5a7b33d7726e2f86570981b6ece0c88dcee807
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,551 @@
+# Open3DForge — Full Build Plan
+
+> **Project:** Personal image-to-game-ready 3D asset pipeline
+> **Owner:** Basel · Solo dev for "What Remains" (UE5.7)
+> **Hosting:** Single HF Pro Space, ZeroGPU H200, 25 min/day quota
+> **SDK:** Gradio 6.x (currently 6.14.0)
+> **Repo:** `Reverb/open3dforge`
+
+---
+
+## Architectural Decisions (Locked In)
+
+These were debated and decided during early development. Don't relitigate them mid-build.
+
+1. **One Space, not multiple.** Option B: vendor TRELLIS.2 + Hunyuan3D-2 + UniRig into this Space rather than orchestrating across multiple Spaces via `gradio_client`. Larger repo, but single deployment, no inter-Space latency, no auth juggling.
+
+2. **HF Space only, no local fallback.** Don't build a path for running on the RTX 4070. Quota is enough for personal use.
+
+3. **Gradio 6.x.** Match the `sdk_version` in `README.md`. No upper bound in `requirements.txt`.
+
+4. **UE5-first export defaults.** DirectX normals, ORM packing, cm units, Z-up, `SM_/SK_/T_` naming.
+
+5. **Drop the custom website.** Standard Gradio tabs. `gradio.Server` is not worth the work for one user.
+
+6. **Drop CHORD.** Research-only license. Use TRELLIS.2's own metallic/roughness volume attributes instead, which are already correct and license-compatible.
+
+7. **nvdiffrast for all baking.** Not Blender headless. Fast (~2-5s per bake), GPU-based, fits inside `@spaces.GPU`, no apt install needed beyond what TRELLIS already requires.
+
+8. **Solo-user workspace pattern.** One `workspace/current/` folder. No session IDs, no multi-tenancy.
+
+---
+
+## Reference Code: Pipeline Stage Order
+
+```
+INPUT: 1-4 images
+ │
+ ├── rembg (background removal, CPU)
+ │
+ ▼
+[Stage 1] GENERATION [GPU]
+ ├── TRELLIS.2 (hard surface) or Hunyuan3D-2 (organic)
+ ├── SAVE high_poly.glb (kept for normal baking)
+ └── Extract: albedo + metallic + roughness volume attrs
+ │
+ ▼
+[Stage 2] POST-PROCESSING [CPU + GPU baking]
+ 2A Mesh repair pymeshfix CPU
+ 2B Geometry cleanup PyMeshLab CPU
+ 2C Decimation CPU
+ ├── Preview: fast-simplification
+ └── Final: PyMeshLab quality pass
+ 2D Symmetry (characters) PyMeshLab CPU
+ 2E UV unwrap xatlas CPU
+ (texels_per_unit packing)
+ 2F Normal bake nvdiffrast GPU
+ DX + GL outputs
+ 2G Albedo bake nvdiffrast GPU
+ vertex color → UV atlas
+ 2H Material bake nvdiffrast GPU
+ TRELLIS volume attrs → UV
+ 2I AO bake nvdiffrast GPU
+ ray-occlusion → UV
+ 2J Texture inpaint (opt) SDXL inpaint GPU
+ hidden UV regions
+ 2K Channel pack numpy CPU
+ Unreal ORM / Unity MetSmooth
+ 2L LOD generation PyMeshLab CPU
+ LOD0/LOD1/LOD2 only (UE5 HLOD handles billboards)
+ 2M Collision mesh CoACD CPU
+ 2N Pivot correction trimesh CPU
+ 2O Scale validation trimesh CPU
+ │
+ ▼
+[Stage 3] AUTO-RIGGING (Optional) [GPU]
+ UniRig → rigged.glb / rigged.fbx
+ │
+ ▼
+[Stage 4] EXPORT
+ UE5 preset (default) → DX normals + ORM
+ Naming: SM_/SK_/T_ convention
+ → export_AssetName_UE5.zip
+```
+
+---
+
+## Milestone Plan
+
+Each milestone is sized to be one focused work session. Push at the end of each, verify, then move on.
+
+---
+
+### ✅ Milestone 1 — Foundation (COMPLETE)
+
+**Status:** Deployed and verified. ZeroGPU smoke test passes.
+
+What got built:
+- HF Space scaffolded with Gradio 6 + ZeroGPU
+- 5 tabs: Generate / Post-Process / Auto-Rig / Export / Presets + Diagnostics
+- `workspace/` folder pattern (current/exports/presets/history)
+- `src/workspace.py` — AssetState, preset save/load
+- `src/quota.py` — daily quota tracking
+- `src/ui_helpers.py` — status bar, asset summary, viewer model picker
+- `gr.Model3D` viewer wired up
+- Pipeline stubs returning placeholder messages
+- Diagnostics tab with `@spaces.GPU` smoke test
+
+Files in repo:
+```
+open3dforge/
+├── README.md ← sdk_version: 6.14.0
+├── requirements.txt ← gradio>=5.0, spaces, numpy, pillow
+├── .gitignore
+├── app.py ← main entry, all UI wiring
+├── src/
+│ ├── __init__.py
+│ ├── workspace.py
+│ ├── quota.py
+│ └── ui_helpers.py
+└── workspace/
+ ├── current/.gitkeep
+ ├── exports/.gitkeep
+ ├── presets/.gitkeep
+ └── history/.gitkeep
+```
+
+---
+
+### 🟡 Milestone 2 — Stage 1: TRELLIS.2 Generation (NEXT)
+
+**Goal:** Real image-to-3D generation working end-to-end. Upload image → get a GLB in the viewer.
+
+**Approach:** Option B — duplicate the microsoft/TRELLIS.2 Space, merge its contents into our repo, then refactor app.py to integrate with our tab structure.
+
+**Step-by-step:**
+
+1. **Duplicate microsoft/TRELLIS.2 Space** to get a known-good baseline:
+ - On HF: `huggingface.co/spaces/microsoft/TRELLIS.2` → Duplicate this Space → name it `open3dforge-trellis-staging`
+ - This is a *staging* copy — we don't deploy it, we just clone it locally for the merge
+ - Confirm it builds and runs in your duplicate before touching anything
+
+2. **Clone both repos locally:**
+ ```bash
+ git clone https://huggingface.co/spaces/Reverb/open3dforge
+ git clone https://huggingface.co/spaces/baselanaya/open3dforge-trellis-staging
+ ```
+
+3. **Copy TRELLIS.2 assets into open3dforge:**
+ ```bash
+ cp -r open3dforge-trellis-staging/trellis2/ open3dforge/
+ cp -r open3dforge-trellis-staging/assets/ open3dforge/
+ cp open3dforge-trellis-staging/autotune_cache.json open3dforge/
+ cp open3dforge-trellis-staging/packages.txt open3dforge/
+ ```
+ This gives us the vendored `trellis2/` Python package, HDRI envmaps, FlexGemm cache, and apt deps.
+
+4. **Merge requirements.txt:**
+ Combine the TRELLIS.2 requirements with our existing ones. Add to `requirements.txt`:
+ ```
+ # TRELLIS.2 deps (from microsoft/TRELLIS.2 Space)
+ torch
+ torchvision
+ cv2 / opencv-python-headless
+ imageio
+ imageio-ffmpeg
+ rembg
+ # plus the custom wheels they install at build time
+ ```
+ Copy theirs verbatim and add to ours. Inspect the resolved `requirements.txt` in the staging duplicate first.
+
+5. **Refactor app.py to integrate the TRELLIS handlers:**
+ - Move TRELLIS pipeline init to module level (per ZeroGPU rules — must be on CUDA at module-level)
+ - Wrap their `image_to_3d` + `extract_glb` functions as the implementation of our existing `stub_generate` handler
+ - Update the Generate tab to match TRELLIS parameter names (resolution, ss_sampling_steps, etc.)
+ - Hide most TRELLIS knobs behind the "Advanced" accordion; expose only Quality preset + Seed at top level
+ - Keep our quality presets (Fast/Balanced/Hero) mapping to their parameter sets
+ - Hook the output GLB into `workspace.get_state().raw_gen_glb` and save the high-poly separately
+
+6. **Critical: save `high_poly.glb` before decimation.** TRELLIS's `extract_glb` calls `o_voxel.postprocess.to_glb(decimation_target=...)`. We need to call it once with no decimation (or a very high target like 16M faces — the nvdiffrast limit they use) to get the high-poly we'll bake from in Stage 2, then call it again with the user's chosen decimation_target for the working low-poly.
+
+7. **Update workspace state on success:**
+ ```python
+ state = workspace.get_state()
+ state.high_poly_glb = Path("workspace/current/high_poly.glb")
+ state.raw_gen_glb = Path("workspace/current/raw_gen.glb")
+ state.face_count = len(mesh.faces)
+ state.vertex_count = len(mesh.vertices)
+ state.model_used = "TRELLIS.2"
+ ```
+
+8. **Test:**
+ - Push to Space
+ - Wait for build (~10-15 min due to CUDA wheels compiling)
+ - Upload a test image
+ - Confirm the GLB appears in the viewer
+ - Confirm Diagnostics quota tracker shows time consumed
+
+**Quality presets to wire up (map to TRELLIS params):**
+
+| Preset | resolution | ss_steps | shape_steps | tex_steps | Expected time |
+|---|---|---|---|---|---|
+| Fast | 512 | 8 | 8 | 8 | ~30s |
+| Balanced | 1024 | 12 | 12 | 12 | ~60s |
+| Hero | 1536 | 16 | 16 | 16 | ~90s |
+
+**Risk mitigation:**
+- TRELLIS.2 build can fail in many ways (CUDA wheel compilation, flash-attn install). If a build fails, check the build logs for which wheel failed. The staging duplicate is the reference — if it built there, the issue is in *your* merge.
+- Don't move anything into `@spaces.GPU` functions that should be at module level. Pipeline init goes at module level.
+
+---
+
+### Milestone 2b — Hunyuan3D-2 Alternative Generator
+
+**Goal:** Second generator option for organic shapes (characters, creatures).
+
+**Approach:** Same duplicate-and-vendor pattern as Milestone 2.
+
+1. Duplicate `tencent/Hunyuan3D-2` to staging Space
+2. Clone, copy the `hy3dgen/` package into open3dforge
+3. Merge requirements (most overlap with TRELLIS.2 — torch, diffusers)
+4. Add Hunyuan pipeline init at module level
+5. The model dropdown in the Generate tab routes between `image_to_3d_trellis()` and `image_to_3d_hunyuan()`
+6. Hunyuan needs 16GB VRAM — fits alongside TRELLIS in H200's 70GB but only load one at a time via lazy module-level guards
+
+**Decision deferred to this milestone:** Whether to keep both models in VRAM at module load (faster, more memory) or lazy-load per call (slower first call, less memory). Test both.
+
+---
+
+### Milestone 3 — Stage 2A-2C: Mesh Cleanup
+
+**Goal:** Working CPU-side mesh repair, cleanup, and decimation with live preview.
+
+**Dependencies to add:**
+```
+trimesh[easy]
+pymeshfix
+pymeshlab
+fast-simplification
+```
+
+**Files to create:**
+- `src/stages/__init__.py`
+- `src/stages/stage2_repair.py` — pymeshfix wrapper
+- `src/stages/stage2_cleanup.py` — PyMeshLab filter chain
+- `src/stages/stage2_decimate.py` — both fast-simplification (preview) and PyMeshLab (final)
+
+**UI work in app.py:**
+- Wire the existing checkboxes/sliders in Tab 2 to call the real implementations
+- Live preview: slider `.change()` event fires `fast-simplification`, updates face count display
+- Run button: actually runs full pipeline on the current GLB
+
+**Workspace state updates:**
+- `state.repaired_glb`, `state.cleaned_glb`, `state.low_poly_glb` all get populated as steps complete
+
+**Test criteria:**
+- Generate a TRELLIS asset (50k faces)
+- Run repair → no errors
+- Run cleanup → no errors
+- Set decimation slider to 10k → live preview updates face count
+- Click "Run final" → produces low_poly.glb at 10k faces
+- Viewer auto-refreshes to show the cleaned mesh
+
+---
+
+### Milestone 4 — Stage 2D-2E: Symmetry + UV Unwrap
+
+**Goal:** Symmetry enforcement + xatlas UV unwrapping with consistent texel density.
+
+**Dependencies to add:**
+```
+xatlas
+```
+
+**Files to create:**
+- `src/stages/stage2_symmetry.py` — PyMeshLab `apply_filter_mesh_symmetrize`
+- `src/stages/stage2_uv.py` — xatlas with `texels_per_unit` packing
+
+**UI work:**
+- Symmetry: off / bilateral-X / bilateral-Y / radial dropdown
+- UV: atlas resolution, texels_per_unit, padding
+
+**Test criteria:**
+- Run on a human-character GLB → symmetry produces clean mirror
+- UV unwrap produces `unwrapped.glb` with valid UV0 coords visible if you inspect via trimesh
+- No overlapping UV islands (check with PyMeshLab's quality measure)
+
+---
+
+### Milestone 5 — Stage 2F: Normal Baking with nvdiffrast
+
+**Goal:** High-poly → low-poly normal map baking, GPU-accelerated, 2-5 second bakes.
+
+**Dependencies to add:**
+- `nvdiffrast` (already installed via TRELLIS.2 wheels — verify in the staging duplicate)
+
+**Files to create:**
+- `src/stages/stage2_bake_normal.py` — full nvdiffrast pipeline
+
+**Algorithm (from the plan doc):**
+```python
+@spaces.GPU(duration=60)
+def bake_normal_map(high_poly_path, low_poly_path, uv_coords, map_size=2048):
+ ctx = dr.RasterizeCudaContext()
+ # 1. UV → clip space
+ # 2. Rasterize low-poly UVs → per-pixel world position + tri ID
+ # 3. For each pixel: nearest-on-surface from high-poly
+ # 4. Sample high-poly normal at that point
+ # 5. Transform to tangent space (low-poly tangent frame)
+ # 6. Pack RGB [0,1], save PNG
+ # 7. Dilate edges past UV island boundaries
+```
+
+**Output:** Two PNGs — `normal_gl.png` and `normal_dx.png` (DX has Y-flipped green channel).
+
+**Test criteria:**
+- Run on TRELLIS character output (50k high-poly → 10k low-poly)
+- Bake completes in <10 seconds
+- Open the normal map in any image viewer — should be bluish/purple with surface detail visible
+- Both DX and GL versions are produced
+- Quota shows 5-10 seconds consumed
+
+---
+
+### Milestone 6 — Stage 2G-2I: Albedo, Material, AO Baking
+
+**Goal:** Three more nvdiffrast bakes producing the full PBR texture set.
+
+**Files to create:**
+- `src/stages/stage2_bake_albedo.py`
+- `src/stages/stage2_bake_material.py` — uses TRELLIS.2's stored metallic+roughness attrs
+- `src/stages/stage2_bake_ao.py` — ray-occlusion in hemisphere
+
+**Key reuse:** Same nvdiffrast rasterization pattern as Milestone 5 — refactor that code into a shared helper `_rasterize_uv_atlas()` in `src/stages/_baking_helpers.py`.
+
+**Workspace state:** All texture paths populated on the AssetState.
+
+**Test criteria:**
+- All four maps (normal, albedo, metallic, roughness, AO) viewable as PNG thumbnails in Tab 2
+- Total Stage 2 baking time < 30 seconds for a Balanced-quality asset
+
+---
+
+### Milestone 7 — Stage 2J: SDXL Inpainting for Hidden UVs
+
+**Goal:** Detect stretched/synthetic UV regions and inpaint them with SDXL.
+
+**Dependencies to add:**
+```
+diffusers
+accelerate
+safetensors
+```
+
+**Files to create:**
+- `src/stages/stage2_inpaint.py`
+ - `detect_hidden_regions(albedo, uvs, faces)` — variance analysis
+ - `inpaint_hidden_uvs(...)` — SDXL inpainting pipeline
+
+**UI:** Toggle off by default (costs ~30s quota). Prompt input. Strength slider.
+
+**Test criteria:**
+- Generate an asset with a clear "back side" (e.g., a humanoid character)
+- Without inpainting: back of character has visible texture stretching
+- With inpainting: back is plausibly filled in
+- Quota cost: ~30s per inpaint
+
+---
+
+### Milestone 8 — Stage 2K-2O: Finalization Steps
+
+**Goal:** Channel packing, LODs, collision, pivot, scale — all CPU-side, fast.
+
+**Dependencies to add:**
+```
+coacd==1.0.4
+```
+
+**Files to create:**
+- `src/stages/stage2_channel_pack.py` — numpy ORM / MetallicSmoothness packing
+- `src/stages/stage2_lods.py` — PyMeshLab quality-aware LOD0/1/2
+- `src/stages/stage2_collision.py` — CoACD with `trimesh.convex_hull` fallback
+- `src/stages/stage2_pivot.py` — bottom_center / geometric_center / custom
+- `src/stages/stage2_scale.py` — height presets, UE5 cm units
+
+**UI:** All controls already scaffolded in Milestone 1's Post-Process tab. Just wire to real implementations.
+
+**Test criteria:**
+- ORM packed as RGB with AO/Roughness/Metallic in correct channels
+- LOD0/LOD1/LOD2 all generated, all share same UV layout
+- Collision mesh has <1% the triangle count of LOD0
+- Pivot at bottom_center for a generated human character results in feet at world origin Y=0
+- Scale: human asset is 1.8m tall = 180cm in UE5 export
+
+---
+
+### Milestone 9 — Stage 3: UniRig Auto-Rigging
+
+**Goal:** Generate a skeleton + skinning weights for character meshes.
+
+**Approach:** Same vendor-the-Space pattern as Milestone 2.
+
+1. Duplicate `MohamedRashad/UniRig` Space → staging
+2. Verify it builds in the staging duplicate
+3. Copy `UniRig/` package into our repo
+4. Merge requirements
+5. Wire to the Auto-Rig tab handler
+6. Output: rigged FBX (UE5 default) or GLB
+
+**Test criteria:**
+- Run on a humanoid character (after full Stage 2 processing)
+- Output FBX imports into UE5 as a Skeletal Mesh
+- Drag into Mixamo → animations auto-attach correctly
+
+---
+
+### Milestone 10 — Stage 4: UE5 Export
+
+**Goal:** Bundle everything into a UE5-ready zip with proper naming and packing.
+
+**Dependencies to add:**
+```
+pygltflib
+```
+
+**Files to create:**
+- `src/stages/stage4_export.py`
+ - `export_ue5(asset_state, asset_name, asset_type) → zip_path`
+ - Handles FBX conversion via trimesh
+ - Applies naming convention (`SM_`, `SK_`, `T_`)
+ - Writes ORM-packed textures to correct paths
+ - Zip + drop in `workspace/exports/`
+
+**Engine presets (only UE5 fully implemented):**
+- UE5: FBX, DX normals, ORM, Z-up, cm — the default
+- Unity HDRP: FBX, GL normals, MetallicSmoothness, Y-up, m — stub for later
+- Godot/Blender/Web: stubs
+
+**Test criteria:**
+- Export a character → unzip → 6-7 files following naming convention
+- Import to UE5: drag-drop the zip's contents → no warnings, materials auto-create from textures
+- Both Static Mesh and Skeletal Mesh paths work
+
+---
+
+### Milestone 11 — Presets System
+
+**Goal:** Save and load named parameter configurations across tabs.
+
+**Files to update:**
+- `src/workspace.py` — already has `save_preset/load_preset/delete_preset`, just needs the JSON schema fleshed out
+- `app.py` — wire the Presets tab's Save button to actually read all current tab values
+
+**Schema:**
+```json
+{
+ "name": "character_UE5_hero",
+ "stage1": { ... },
+ "stage2": { ... },
+ "stage3": { ... },
+ "stage4": { ... }
+}
+```
+
+**Ship five default presets:**
+- `character_UE5_hero.json`
+- `character_UE5_npc.json`
+- `prop_UE5_hero.json`
+- `prop_UE5_standard.json`
+- `environment_UE5_background.json`
+
+---
+
+### Milestone 12 — Polish & Production Hardening
+
+- Error handling on every stage (don't crash the app, show clear error in UI)
+- Progress bars during long ops (`gr.Progress(track_tqdm=True)`)
+- Quota cost shown *before* each GPU operation (warning if it would exceed remaining)
+- Game-ready checklist passes shown before allowing Export
+- Asset history sidebar (last 5 generated assets with thumbnails)
+- Session cleanup of `workspace/current/` on new generation
+
+---
+
+## Working with Claude Code
+
+When you continue in Claude Code, you'll have the full repo locally. Key things to remember:
+
+### Project conventions
+
+1. **Each stage = its own module** in `src/stages/`. Don't dump pipeline logic into `app.py`.
+2. **Workspace state is the single source of truth.** Every stage reads from and writes to `workspace.get_state()`.
+3. **GPU functions live where they're needed**, not all in app.py. The `@spaces.GPU` decorator works in any file as long as `spaces` is imported.
+4. **No `if __name__ == "__main__":` on `demo.launch()`.** HF Spaces imports app.py at module level.
+5. **Gradio 6 specifics:**
+ - `theme` and `css` go in `launch()`, not `Blocks()`
+ - `show_api` is gone — use `footer_links=["gradio", "settings"]`
+ - `api_visibility` replaces `api_name=False` on events
+6. **The 3 global components** (`viewer`, `summary`, `status_bar`) get refreshed via `_global_refresh()` chained off every pipeline action button. Don't forget to add new buttons to that list.
+
+### Useful commands
+
+```bash
+# Pull the latest Space state
+cd open3dforge
+git pull
+
+# Make changes, syntax-check before push
+python -c "import ast; ast.parse(open('app.py').read())"
+
+# Push to deploy
+git add -A
+git commit -m "Milestone N: "
+git push
+
+# Watch build/runtime logs at:
+# https://huggingface.co/spaces/Reverb/open3dforge?logs=container
+```
+
+### Common HF Space build failures (we've hit these)
+
+| Symptom | Cause | Fix |
+|---|---|---|
+| `Cannot install gradio
+ function refreshView(mode, step) {
+ // 1. Find current mode and step
+ const allImgs = document.querySelectorAll('.previewer-main-image');
+ for (let i = 0; i < allImgs.length; i++) {
+ const img = allImgs[i];
+ if (img.classList.contains('visible')) {
+ const id = img.id;
+ const [_, m, s] = id.split('-');
+ if (mode === -1) mode = parseInt(m.slice(1));
+ if (step === -1) step = parseInt(s.slice(1));
+ break;
+ }
+ }
+
+ // 2. Hide ALL images
+ // We select all elements with class 'previewer-main-image'
+ allImgs.forEach(img => img.classList.remove('visible'));
+
+ // 3. Construct the specific ID for the current state
+ // Format: view-m{mode}-s{step}
+ const targetId = 'view-m' + mode + '-s' + step;
+ const targetImg = document.getElementById(targetId);
+
+ // 4. Show ONLY the target
+ if (targetImg) {
+ targetImg.classList.add('visible');
+ }
+
+ // 5. Update Button Highlights
+ const allBtns = document.querySelectorAll('.mode-btn');
+ allBtns.forEach((btn, idx) => {
+ if (idx === mode) btn.classList.add('active');
+ else btn.classList.remove('active');
+ });
+ }
+
+ // --- Action: Switch Mode ---
+ function selectMode(mode) {
+ refreshView(mode, -1);
+ }
+
+ // --- Action: Slider Change ---
+ function onSliderChange(val) {
+ refreshView(-1, parseInt(val));
+ }
+
+"""
+
+
+empty_html = f"""
+
+"""
+
+
+def image_to_base64(image):
+ buffered = io.BytesIO()
+ image = image.convert("RGB")
+ image.save(buffered, format="jpeg", quality=85)
+ img_str = base64.b64encode(buffered.getvalue()).decode()
+ return f"data:image/jpeg;base64,{img_str}"
+
+
+def start_session(req: gr.Request):
+ user_dir = os.path.join(TMP_DIR, str(req.session_hash))
+ os.makedirs(user_dir, exist_ok=True)
+
+
+def end_session(req: gr.Request):
+ user_dir = os.path.join(TMP_DIR, str(req.session_hash))
+ shutil.rmtree(user_dir)
+
+
+def remove_background(input: Image.Image) -> Image.Image:
+ with tempfile.NamedTemporaryFile(suffix='.png') as f:
+ input = input.convert('RGB')
+ input.save(f.name)
+ output = rmbg_client.predict(handle_file(f.name), api_name="/image")[0][0]
+ output = Image.open(output)
+ return output
+
+
+def preprocess_image(input: Image.Image) -> Image.Image:
+ """
+ Preprocess the input image.
+ """
+ # if has alpha channel, use it directly; otherwise, remove background
+ has_alpha = False
+ if input.mode == 'RGBA':
+ alpha = np.array(input)[:, :, 3]
+ if not np.all(alpha == 255):
+ has_alpha = True
+ max_size = max(input.size)
+ scale = min(1, 1024 / max_size)
+ if scale < 1:
+ input = input.resize((int(input.width * scale), int(input.height * scale)), Image.Resampling.LANCZOS)
+ if has_alpha:
+ output = input
+ else:
+ output = remove_background(input)
+ output_np = np.array(output)
+ alpha = output_np[:, :, 3]
+ bbox = np.argwhere(alpha > 0.8 * 255)
+ bbox = np.min(bbox[:, 1]), np.min(bbox[:, 0]), np.max(bbox[:, 1]), np.max(bbox[:, 0])
+ center = (bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2
+ size = max(bbox[2] - bbox[0], bbox[3] - bbox[1])
+ size = int(size * 1)
+ bbox = center[0] - size // 2, center[1] - size // 2, center[0] + size // 2, center[1] + size // 2
+ output = output.crop(bbox) # type: ignore
+ output = np.array(output).astype(np.float32) / 255
+ output = output[:, :, :3] * output[:, :, 3:4]
+ output = Image.fromarray((output * 255).astype(np.uint8))
+ return output
+
+
+def pack_state(latents: Tuple[SparseTensor, SparseTensor, int]) -> dict:
+ shape_slat, tex_slat, res = latents
+ return {
+ 'shape_slat_feats': shape_slat.feats.cpu().numpy(),
+ 'tex_slat_feats': tex_slat.feats.cpu().numpy(),
+ 'coords': shape_slat.coords.cpu().numpy(),
+ 'res': res,
+ }
+
+
+def unpack_state(state: dict) -> Tuple[SparseTensor, SparseTensor, int]:
+ shape_slat = SparseTensor(
+ feats=torch.from_numpy(state['shape_slat_feats']).cuda(),
+ coords=torch.from_numpy(state['coords']).cuda(),
+ )
+ tex_slat = shape_slat.replace(torch.from_numpy(state['tex_slat_feats']).cuda())
+ return shape_slat, tex_slat, state['res']
+
+
+def get_seed(randomize_seed: bool, seed: int) -> int:
+ """
+ Get the random seed.
+ """
+ return np.random.randint(0, MAX_SEED) if randomize_seed else seed
+
+
+@spaces.GPU(duration=120)
+def image_to_3d(
+ image: Image.Image,
+ seed: int,
+ resolution: str,
+ ss_guidance_strength: float,
+ ss_guidance_rescale: float,
+ ss_sampling_steps: int,
+ ss_rescale_t: float,
+ shape_slat_guidance_strength: float,
+ shape_slat_guidance_rescale: float,
+ shape_slat_sampling_steps: int,
+ shape_slat_rescale_t: float,
+ tex_slat_guidance_strength: float,
+ tex_slat_guidance_rescale: float,
+ tex_slat_sampling_steps: int,
+ tex_slat_rescale_t: float,
+ req: gr.Request,
+ progress=gr.Progress(track_tqdm=True),
+) -> str:
+ # --- Sampling ---
+ outputs, latents = pipeline.run(
+ image,
+ seed=seed,
+ preprocess_image=False,
+ sparse_structure_sampler_params={
+ "steps": ss_sampling_steps,
+ "guidance_strength": ss_guidance_strength,
+ "guidance_rescale": ss_guidance_rescale,
+ "rescale_t": ss_rescale_t,
+ },
+ shape_slat_sampler_params={
+ "steps": shape_slat_sampling_steps,
+ "guidance_strength": shape_slat_guidance_strength,
+ "guidance_rescale": shape_slat_guidance_rescale,
+ "rescale_t": shape_slat_rescale_t,
+ },
+ tex_slat_sampler_params={
+ "steps": tex_slat_sampling_steps,
+ "guidance_strength": tex_slat_guidance_strength,
+ "guidance_rescale": tex_slat_guidance_rescale,
+ "rescale_t": tex_slat_rescale_t,
+ },
+ pipeline_type={
+ "512": "512",
+ "1024": "1024_cascade",
+ "1536": "1536_cascade",
+ }[resolution],
+ return_latent=True,
+ )
+ mesh = outputs[0]
+ mesh.simplify(16777216) # nvdiffrast limit
+ images = render_utils.render_snapshot(mesh, resolution=1024, r=2, fov=36, nviews=STEPS, envmap=envmap)
+ state = pack_state(latents)
+ torch.cuda.empty_cache()
+
+ # --- HTML Construction ---
+ # The Stack of 48 Images
+ images_html = ""
+ for m_idx, mode in enumerate(MODES):
+ for s_idx in range(STEPS):
+ # ID Naming Convention: view-m{mode}-s{step}
+ unique_id = f"view-m{m_idx}-s{s_idx}"
+
+ # Logic: Only Mode 0, Step 0 is visible initially
+ is_visible = (m_idx == DEFAULT_MODE and s_idx == DEFAULT_STEP)
+ vis_class = "visible" if is_visible else ""
+
+ # Image Source
+ img_base64 = image_to_base64(Image.fromarray(images[mode['render_key']][s_idx]))
+
+ # Render the Tag
+ images_html += f"""
+
+ """
+
+ # Button Row HTML
+ btns_html = ""
+ for idx, mode in enumerate(MODES):
+ active_class = "active" if idx == DEFAULT_MODE else ""
+ # Note: onclick calls the JS function defined in Head
+ btns_html += f"""
+
+ """
+
+ # Assemble the full component
+ full_html = f"""
+
+
+
💡Tips
+
+
● Render Mode - Click on the circular buttons to switch between different render modes.
+
● View Angle - Drag the slider to change the view angle.
+
+
+
+
+
+ {images_html}
+
+
+
+
+ {btns_html}
+
+
+
+
+
+
+
+ """
+
+ return state, full_html
+
+
+@spaces.GPU(duration=120)
+def extract_glb(
+ state: dict,
+ decimation_target: int,
+ texture_size: int,
+ req: gr.Request,
+ progress=gr.Progress(track_tqdm=True),
+) -> Tuple[str, str]:
+ """
+ Extract a GLB file from the 3D model.
+
+ Args:
+ state (dict): The state of the generated 3D model.
+ decimation_target (int): The target face count for decimation.
+ texture_size (int): The texture resolution.
+
+ Returns:
+ str: The path to the extracted GLB file.
+ """
+ user_dir = os.path.join(TMP_DIR, str(req.session_hash))
+ shape_slat, tex_slat, res = unpack_state(state)
+ mesh = pipeline.decode_latent(shape_slat, tex_slat, res)[0]
+ mesh.simplify(16777216)
+ glb = o_voxel.postprocess.to_glb(
+ vertices=mesh.vertices,
+ faces=mesh.faces,
+ attr_volume=mesh.attrs,
+ coords=mesh.coords,
+ attr_layout=pipeline.pbr_attr_layout,
+ grid_size=res,
+ aabb=[[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]],
+ decimation_target=decimation_target,
+ texture_size=texture_size,
+ remesh=True,
+ remesh_band=1,
+ remesh_project=0,
+ use_tqdm=True,
+ )
+ now = datetime.now()
+ timestamp = now.strftime("%Y-%m-%dT%H%M%S") + f".{now.microsecond // 1000:03d}"
+ os.makedirs(user_dir, exist_ok=True)
+ glb_path = os.path.join(user_dir, f'sample_{timestamp}.glb')
+ glb.export(glb_path, extension_webp=True)
+ torch.cuda.empty_cache()
+ return glb_path, glb_path
+
+
+with gr.Blocks(delete_cache=(600, 600)) as demo:
+ gr.Markdown("""
+ ## Image to 3D Asset with [TRELLIS.2](https://microsoft.github.io/TRELLIS.2)
+ * Upload an image (preferably with an alpha-masked foreground object) and click Generate to create a 3D asset.
+ * Click Extract GLB to export and download the generated GLB file if you're satisfied with the result. Otherwise, try another time.
+ """)
+
+ with gr.Row():
+ with gr.Column(scale=1, min_width=360):
+ image_prompt = gr.Image(label="Image Prompt", format="png", image_mode="RGBA", type="pil", height=400)
+
+ resolution = gr.Radio(["512", "1024", "1536"], label="Resolution", value="1024")
+ seed = gr.Slider(0, MAX_SEED, label="Seed", value=0, step=1)
+ randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
+ decimation_target = gr.Slider(100000, 500000, label="Decimation Target", value=300000, step=10000)
+ texture_size = gr.Slider(1024, 4096, label="Texture Size", value=2048, step=1024)
+
+ generate_btn = gr.Button("Generate")
+
+ with gr.Accordion(label="Advanced Settings", open=False):
+ gr.Markdown("Stage 1: Sparse Structure Generation")
+ with gr.Row():
+ ss_guidance_strength = gr.Slider(1.0, 10.0, label="Guidance Strength", value=7.5, step=0.1)
+ ss_guidance_rescale = gr.Slider(0.0, 1.0, label="Guidance Rescale", value=0.7, step=0.01)
+ ss_sampling_steps = gr.Slider(1, 50, label="Sampling Steps", value=12, step=1)
+ ss_rescale_t = gr.Slider(1.0, 6.0, label="Rescale T", value=5.0, step=0.1)
+ gr.Markdown("Stage 2: Shape Generation")
+ with gr.Row():
+ shape_slat_guidance_strength = gr.Slider(1.0, 10.0, label="Guidance Strength", value=7.5, step=0.1)
+ shape_slat_guidance_rescale = gr.Slider(0.0, 1.0, label="Guidance Rescale", value=0.5, step=0.01)
+ shape_slat_sampling_steps = gr.Slider(1, 50, label="Sampling Steps", value=12, step=1)
+ shape_slat_rescale_t = gr.Slider(1.0, 6.0, label="Rescale T", value=3.0, step=0.1)
+ gr.Markdown("Stage 3: Material Generation")
+ with gr.Row():
+ tex_slat_guidance_strength = gr.Slider(1.0, 10.0, label="Guidance Strength", value=1.0, step=0.1)
+ tex_slat_guidance_rescale = gr.Slider(0.0, 1.0, label="Guidance Rescale", value=0.0, step=0.01)
+ tex_slat_sampling_steps = gr.Slider(1, 50, label="Sampling Steps", value=12, step=1)
+ tex_slat_rescale_t = gr.Slider(1.0, 6.0, label="Rescale T", value=3.0, step=0.1)
+
+ with gr.Column(scale=10):
+ with gr.Walkthrough(selected=0) as walkthrough:
+ with gr.Step("Preview", id=0):
+ preview_output = gr.HTML(empty_html, label="3D Asset Preview", show_label=True, container=True)
+ extract_btn = gr.Button("Extract GLB")
+ with gr.Step("Extract", id=1):
+ glb_output = gr.Model3D(label="Extracted GLB", height=724, show_label=True, display_mode="solid", clear_color=(0.25, 0.25, 0.25, 1.0))
+ download_btn = gr.DownloadButton(label="Download GLB")
+ gr.Markdown("*We are actively working on improving the speed of GLB extraction. Currently, it may take half a minute or more and face count is limited.*")
+
+ with gr.Column(scale=1, min_width=172):
+ examples = gr.Examples(
+ examples=[
+ f'assets/example_image/{image}'
+ for image in os.listdir("assets/example_image")
+ ],
+ inputs=[image_prompt],
+ fn=preprocess_image,
+ outputs=[image_prompt],
+ run_on_click=True,
+ examples_per_page=18,
+ )
+
+ output_buf = gr.State()
+
+
+ # Handlers
+ demo.load(start_session)
+ demo.unload(end_session)
+
+ image_prompt.upload(
+ preprocess_image,
+ inputs=[image_prompt],
+ outputs=[image_prompt],
+ )
+
+ generate_btn.click(
+ get_seed,
+ inputs=[randomize_seed, seed],
+ outputs=[seed],
+ ).then(
+ lambda: gr.Walkthrough(selected=0), outputs=walkthrough
+ ).then(
+ image_to_3d,
+ inputs=[
+ image_prompt, seed, resolution,
+ ss_guidance_strength, ss_guidance_rescale, ss_sampling_steps, ss_rescale_t,
+ shape_slat_guidance_strength, shape_slat_guidance_rescale, shape_slat_sampling_steps, shape_slat_rescale_t,
+ tex_slat_guidance_strength, tex_slat_guidance_rescale, tex_slat_sampling_steps, tex_slat_rescale_t,
+ ],
+ outputs=[output_buf, preview_output],
+ )
+
+ extract_btn.click(
+ lambda: gr.Walkthrough(selected=1), outputs=walkthrough
+ ).then(
+ extract_glb,
+ inputs=[output_buf, decimation_target, texture_size],
+ outputs=[glb_output, download_btn],
+ )
+
+
+# Launch the Gradio app
+if __name__ == "__main__":
+ os.makedirs(TMP_DIR, exist_ok=True)
+
+ # Construct ui components
+ btn_img_base64_strs = {}
+ for i in range(len(MODES)):
+ icon = Image.open(MODES[i]['icon'])
+ MODES[i]['icon_base64'] = image_to_base64(icon)
+
+ rmbg_client = Client("briaai/BRIA-RMBG-2.0")
+ pipeline = Trellis2ImageTo3DPipeline.from_pretrained('microsoft/TRELLIS.2-4B')
+ pipeline.rembg_model = None
+ pipeline.low_vram = False
+ pipeline.cuda()
+
+ envmap = {
+ 'forest': EnvMap(torch.tensor(
+ cv2.cvtColor(cv2.imread('assets/hdri/forest.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB),
+ dtype=torch.float32, device='cuda'
+ )),
+ 'sunset': EnvMap(torch.tensor(
+ cv2.cvtColor(cv2.imread('assets/hdri/sunset.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB),
+ dtype=torch.float32, device='cuda'
+ )),
+ 'courtyard': EnvMap(torch.tensor(
+ cv2.cvtColor(cv2.imread('assets/hdri/courtyard.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB),
+ dtype=torch.float32, device='cuda'
+ )),
+ }
+
+ demo.launch(css=css, head=head)
diff --git a/TRELLIS.2/assets/app/basecolor.png b/TRELLIS.2/assets/app/basecolor.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7dbeaf6344b4b292757964eca2c6960e7e10a68
Binary files /dev/null and b/TRELLIS.2/assets/app/basecolor.png differ
diff --git a/TRELLIS.2/assets/app/clay.png b/TRELLIS.2/assets/app/clay.png
new file mode 100644
index 0000000000000000000000000000000000000000..e02866a15d1101d1d1cd3f6098c7025c0763cfdb
Binary files /dev/null and b/TRELLIS.2/assets/app/clay.png differ
diff --git a/TRELLIS.2/assets/app/hdri_city.png b/TRELLIS.2/assets/app/hdri_city.png
new file mode 100644
index 0000000000000000000000000000000000000000..43e1c2a54c3bb8aa376613c698268fca0aea9b29
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_city.png differ
diff --git a/TRELLIS.2/assets/app/hdri_courtyard.png b/TRELLIS.2/assets/app/hdri_courtyard.png
new file mode 100644
index 0000000000000000000000000000000000000000..4261ad62862163d32c22ac38495defdbdf3bebd0
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_courtyard.png differ
diff --git a/TRELLIS.2/assets/app/hdri_forest.png b/TRELLIS.2/assets/app/hdri_forest.png
new file mode 100644
index 0000000000000000000000000000000000000000..7617fe19adf536c12db3f4bf7bc1f6a42f54f8b7
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_forest.png differ
diff --git a/TRELLIS.2/assets/app/hdri_interior.png b/TRELLIS.2/assets/app/hdri_interior.png
new file mode 100644
index 0000000000000000000000000000000000000000..e00c1d656c94c71402e93067cac64725425754d0
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_interior.png differ
diff --git a/TRELLIS.2/assets/app/hdri_night.png b/TRELLIS.2/assets/app/hdri_night.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0423d221069904b0de32c82956675a210e8c375
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_night.png differ
diff --git a/TRELLIS.2/assets/app/hdri_studio.png b/TRELLIS.2/assets/app/hdri_studio.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f5a4e8d5c5717b6ca4217e6e081e695e2bec264
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_studio.png differ
diff --git a/TRELLIS.2/assets/app/hdri_sunrise.png b/TRELLIS.2/assets/app/hdri_sunrise.png
new file mode 100644
index 0000000000000000000000000000000000000000..9cee3bb066a0f01ddf84b088da31fba1af6648d0
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_sunrise.png differ
diff --git a/TRELLIS.2/assets/app/hdri_sunset.png b/TRELLIS.2/assets/app/hdri_sunset.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd67070912b846b7cb353d13696f4aff4be40831
Binary files /dev/null and b/TRELLIS.2/assets/app/hdri_sunset.png differ
diff --git a/TRELLIS.2/assets/app/normal.png b/TRELLIS.2/assets/app/normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..352e92b5750414ee1c2562d1c719468ce5da2883
Binary files /dev/null and b/TRELLIS.2/assets/app/normal.png differ
diff --git a/TRELLIS.2/assets/example_image/0a34fae7ba57cb8870df5325b9c30ea474def1b0913c19c596655b85a79fdee4.webp b/TRELLIS.2/assets/example_image/0a34fae7ba57cb8870df5325b9c30ea474def1b0913c19c596655b85a79fdee4.webp
new file mode 100644
index 0000000000000000000000000000000000000000..8cb4652f561eca8ab3aa32f6e00457bc9b9f194a
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/0a34fae7ba57cb8870df5325b9c30ea474def1b0913c19c596655b85a79fdee4.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:83d3765ff57511f11054d62e6beaf52648d277006b6dcb3c1d5f9e03ef502c49
+size 108096
diff --git a/TRELLIS.2/assets/example_image/0e4984a9b3765ce80e9853443f9319ecedf90885c74b56cccfebc09402740f8a.webp b/TRELLIS.2/assets/example_image/0e4984a9b3765ce80e9853443f9319ecedf90885c74b56cccfebc09402740f8a.webp
new file mode 100644
index 0000000000000000000000000000000000000000..b9dbb51554fe1f2daeb448c0e47cfaa512a07eff
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/0e4984a9b3765ce80e9853443f9319ecedf90885c74b56cccfebc09402740f8a.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a31ba3b084757faa66e4bb91a85bd956fcc1eaaaf298a091fd08044351cd0293
+size 184424
diff --git a/TRELLIS.2/assets/example_image/0f168a4b1b6e96c72e9627c97a212c27a4572250ff58e25703b9d0c2bc74191a.webp b/TRELLIS.2/assets/example_image/0f168a4b1b6e96c72e9627c97a212c27a4572250ff58e25703b9d0c2bc74191a.webp
new file mode 100644
index 0000000000000000000000000000000000000000..62488149f1f5d00ac044ff6f95b91efa6117b7ed
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/0f168a4b1b6e96c72e9627c97a212c27a4572250ff58e25703b9d0c2bc74191a.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a8d419ac16852b73fbc7b92c6857ba5d4be2f2dd8056bf44af707e6af4d62207
+size 156794
diff --git a/TRELLIS.2/assets/example_image/130c2b18f1651a70f8aa15b2c99f8dba29bb943044d92871f9223bd3e989e8b1.webp b/TRELLIS.2/assets/example_image/130c2b18f1651a70f8aa15b2c99f8dba29bb943044d92871f9223bd3e989e8b1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f6a749a33c8ffd111cf198f499bda2b499537d51
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/130c2b18f1651a70f8aa15b2c99f8dba29bb943044d92871f9223bd3e989e8b1.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f1a36d67f1cd7bba5c78b429c85346990aa3f269e19eee60b6d8b5d632cd743a
+size 100332
diff --git a/TRELLIS.2/assets/example_image/154c88671d9e8785bd909e9283bc87fb2709ac7ce13890832603ea7533981a46.webp b/TRELLIS.2/assets/example_image/154c88671d9e8785bd909e9283bc87fb2709ac7ce13890832603ea7533981a46.webp
new file mode 100644
index 0000000000000000000000000000000000000000..3c3ac5dfc7a6d30528928e30eca04f36870f33c3
Binary files /dev/null and b/TRELLIS.2/assets/example_image/154c88671d9e8785bd909e9283bc87fb2709ac7ce13890832603ea7533981a46.webp differ
diff --git a/TRELLIS.2/assets/example_image/1c359e94f2d699055c78487c90626cf5f1d7460c8fc04e60a286507e5286a28d.webp b/TRELLIS.2/assets/example_image/1c359e94f2d699055c78487c90626cf5f1d7460c8fc04e60a286507e5286a28d.webp
new file mode 100644
index 0000000000000000000000000000000000000000..e596271b736281ad07491dd7b7d3544214e2c7aa
Binary files /dev/null and b/TRELLIS.2/assets/example_image/1c359e94f2d699055c78487c90626cf5f1d7460c8fc04e60a286507e5286a28d.webp differ
diff --git a/TRELLIS.2/assets/example_image/22a868bac8e62511fccd2bc82ed31ae77ed31ae2a8a149be7150957f11b30c9b.webp b/TRELLIS.2/assets/example_image/22a868bac8e62511fccd2bc82ed31ae77ed31ae2a8a149be7150957f11b30c9b.webp
new file mode 100644
index 0000000000000000000000000000000000000000..287db1bed9d597e5ff7e4a49da4a63c5529f51c7
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/22a868bac8e62511fccd2bc82ed31ae77ed31ae2a8a149be7150957f11b30c9b.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb7cdcea3b238d40c7b838659288f5c12febd77292b22d44f54f785e2712d49a
+size 159636
diff --git a/TRELLIS.2/assets/example_image/25d412fe36aab9f33913bc9f5e2fb1ff6458bdb286bf14397162c672c95d3697.webp b/TRELLIS.2/assets/example_image/25d412fe36aab9f33913bc9f5e2fb1ff6458bdb286bf14397162c672c95d3697.webp
new file mode 100644
index 0000000000000000000000000000000000000000..bdfc4f52348dc4ea59cae734f9ee0f4aa29484da
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/25d412fe36aab9f33913bc9f5e2fb1ff6458bdb286bf14397162c672c95d3697.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4202eb19d6802319aa140e65385b3474d09aaa7f008218acf1e1f5186b923c90
+size 167372
diff --git a/TRELLIS.2/assets/example_image/26717a7dad644a5cf7554e8e6d06cf82d3dd9bbae31620b36cc7eb38b8de7ac9.webp b/TRELLIS.2/assets/example_image/26717a7dad644a5cf7554e8e6d06cf82d3dd9bbae31620b36cc7eb38b8de7ac9.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ef5029ebcfa044e437caa35458bb6ab860dbda8a
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/26717a7dad644a5cf7554e8e6d06cf82d3dd9bbae31620b36cc7eb38b8de7ac9.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d15269d0c0b427eabcca39d6d093cc2cfdaab19cb8a40b6158988a70a91ffe45
+size 207084
diff --git a/TRELLIS.2/assets/example_image/290af2dd390c95db88a35b8062fdd2ac1a9c28edc6533bc6a26ab2c83c523c61.webp b/TRELLIS.2/assets/example_image/290af2dd390c95db88a35b8062fdd2ac1a9c28edc6533bc6a26ab2c83c523c61.webp
new file mode 100644
index 0000000000000000000000000000000000000000..89889d4b276ba78b3fc451ec6a504c1b5089c859
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/290af2dd390c95db88a35b8062fdd2ac1a9c28edc6533bc6a26ab2c83c523c61.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6cd45dd941dc559191c71f49ac5841fc6d06d32c7427fcf535f38c007611cd3f
+size 109042
diff --git a/TRELLIS.2/assets/example_image/2bb0932314bae71eec94d0d01a20d3f761ade9664e013b9a9a43c00a2f44163a.webp b/TRELLIS.2/assets/example_image/2bb0932314bae71eec94d0d01a20d3f761ade9664e013b9a9a43c00a2f44163a.webp
new file mode 100644
index 0000000000000000000000000000000000000000..962281565b2c60a013e64776313145fd8186e4ef
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/2bb0932314bae71eec94d0d01a20d3f761ade9664e013b9a9a43c00a2f44163a.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c4e26e3e2f3de96cf396c64f1cef39ac82c13f231e2567fe0fe902dc103bf949
+size 169506
diff --git a/TRELLIS.2/assets/example_image/3723615e3766742ae35b09517152a58c36d62b707bc60d7f76f8a6c922add2c0.webp b/TRELLIS.2/assets/example_image/3723615e3766742ae35b09517152a58c36d62b707bc60d7f76f8a6c922add2c0.webp
new file mode 100644
index 0000000000000000000000000000000000000000..0af9ee139499ab072b6068e5fb1d974f99103a30
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/3723615e3766742ae35b09517152a58c36d62b707bc60d7f76f8a6c922add2c0.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:88c65db47f93beed7d6b184c32f9fa27c5f64ced2e3d4f535ad628179763cff8
+size 115508
diff --git a/TRELLIS.2/assets/example_image/3903b87907a6b4947006e6fc7c0c64f40cd98932a02bf0ecf7d6dfae776f3a38.webp b/TRELLIS.2/assets/example_image/3903b87907a6b4947006e6fc7c0c64f40cd98932a02bf0ecf7d6dfae776f3a38.webp
new file mode 100644
index 0000000000000000000000000000000000000000..7411bc618bfd5af692073d70281a857df6932b22
Binary files /dev/null and b/TRELLIS.2/assets/example_image/3903b87907a6b4947006e6fc7c0c64f40cd98932a02bf0ecf7d6dfae776f3a38.webp differ
diff --git a/TRELLIS.2/assets/example_image/39488b45bb4820ff0f31bb07cb8d0a19ebd991adbcb22a10fc89ee41c59219ee.webp b/TRELLIS.2/assets/example_image/39488b45bb4820ff0f31bb07cb8d0a19ebd991adbcb22a10fc89ee41c59219ee.webp
new file mode 100644
index 0000000000000000000000000000000000000000..5f00cc2b4562fb026033a555cf95c946a3922246
Binary files /dev/null and b/TRELLIS.2/assets/example_image/39488b45bb4820ff0f31bb07cb8d0a19ebd991adbcb22a10fc89ee41c59219ee.webp differ
diff --git a/TRELLIS.2/assets/example_image/454e7d8a30486c0635369936e7bec5677b78ae5f436d0e46af0d533738be859f.webp b/TRELLIS.2/assets/example_image/454e7d8a30486c0635369936e7bec5677b78ae5f436d0e46af0d533738be859f.webp
new file mode 100644
index 0000000000000000000000000000000000000000..0a3a3a893b1fa0914e63d79e82d7894afe552483
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/454e7d8a30486c0635369936e7bec5677b78ae5f436d0e46af0d533738be859f.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:47be8271d2d1d27fc334cc470d63534807ad44c6f50cee18a204125a1c6b66a4
+size 140210
diff --git a/TRELLIS.2/assets/example_image/4bc7abe209c8673dd3766ee4fad14d40acbed02d118e7629f645c60fd77313f1.webp b/TRELLIS.2/assets/example_image/4bc7abe209c8673dd3766ee4fad14d40acbed02d118e7629f645c60fd77313f1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6ae86128b367dc0618fd87e605cd08832b6b931b
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/4bc7abe209c8673dd3766ee4fad14d40acbed02d118e7629f645c60fd77313f1.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae7ad70cbb2a616fca63bc73d319172d5fda0930c4aaf9d897e21c09ccf17ad7
+size 167670
diff --git a/TRELLIS.2/assets/example_image/4dae7ef0224e9305533c4801ce8144d5b3a89d883ca5d35bdb0aebb860ff705f.webp b/TRELLIS.2/assets/example_image/4dae7ef0224e9305533c4801ce8144d5b3a89d883ca5d35bdb0aebb860ff705f.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4cb9bdb5ac7fe4bd2ea84771de21eff56dda4cf4
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/4dae7ef0224e9305533c4801ce8144d5b3a89d883ca5d35bdb0aebb860ff705f.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2b5ca8a0b47aa2dbd5480cd356e7ab574dadd565ed738ac5ed655f36a4349eea
+size 175080
diff --git a/TRELLIS.2/assets/example_image/50b70c5f88a5961d2c786158655d2fce5c3b214b2717956500a66a4e5b5fbe37.webp b/TRELLIS.2/assets/example_image/50b70c5f88a5961d2c786158655d2fce5c3b214b2717956500a66a4e5b5fbe37.webp
new file mode 100644
index 0000000000000000000000000000000000000000..01a571a7a2ad661e29c1a4c3b5ba68353451cd70
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/50b70c5f88a5961d2c786158655d2fce5c3b214b2717956500a66a4e5b5fbe37.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:933c10aeebb2920b08cb34a08ab1878817b64eb9e30efdcc3d76731069fc0849
+size 131488
diff --git a/TRELLIS.2/assets/example_image/51b1b31d40476b123db70a51ae0b5f8b8d0db695b616bc2ec4e6324eb178fc14.webp b/TRELLIS.2/assets/example_image/51b1b31d40476b123db70a51ae0b5f8b8d0db695b616bc2ec4e6324eb178fc14.webp
new file mode 100644
index 0000000000000000000000000000000000000000..60375c981e776e3667287f8df99b04f12098f1df
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/51b1b31d40476b123db70a51ae0b5f8b8d0db695b616bc2ec4e6324eb178fc14.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2d5224235eeadadfdb93ab37664055ef55ffd930b085d268cd62c5faf9d101de
+size 136872
diff --git a/TRELLIS.2/assets/example_image/52284bf45134c59a94be150a5b18b9cc3619ada4b30ded8d8d0288383b8c016f.webp b/TRELLIS.2/assets/example_image/52284bf45134c59a94be150a5b18b9cc3619ada4b30ded8d8d0288383b8c016f.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ddd363de151adc06a1815d148a69fce18a238942
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/52284bf45134c59a94be150a5b18b9cc3619ada4b30ded8d8d0288383b8c016f.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:86b909e6847118f2cec6e9c0945e6a78154ce5918f4ba14c0b0afa0be2e8647f
+size 150020
diff --git a/TRELLIS.2/assets/example_image/5a020584b95cf3db3b6420e9b09fb93e7c0f4046e61076e5b4c65c63dc1f5837.webp b/TRELLIS.2/assets/example_image/5a020584b95cf3db3b6420e9b09fb93e7c0f4046e61076e5b4c65c63dc1f5837.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4151759cf55814774c5e1ff29e219e965a21a423
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/5a020584b95cf3db3b6420e9b09fb93e7c0f4046e61076e5b4c65c63dc1f5837.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:62b7097ce57d01e730a0ce2cc120b6c9d27585026c3de84d6b1a0dcaf5fea9d3
+size 128572
diff --git a/TRELLIS.2/assets/example_image/5a6c81d3b2afca4323e4b8b379e2cf06d18371a57fc8c5dc24b57e60e3216690.webp b/TRELLIS.2/assets/example_image/5a6c81d3b2afca4323e4b8b379e2cf06d18371a57fc8c5dc24b57e60e3216690.webp
new file mode 100644
index 0000000000000000000000000000000000000000..cd9120b3d0c12fcec01cf68a27060eba6c658e37
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/5a6c81d3b2afca4323e4b8b379e2cf06d18371a57fc8c5dc24b57e60e3216690.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:47cbe7b6f29adb0f7d02c2cd73f6f8bd90a54b12d416368499458a8c571e35c5
+size 178460
diff --git a/TRELLIS.2/assets/example_image/5c80e5e03a3b60b6f03eaf555ba1dafc0e4230c472d7e8c8e2c5ca0a0dfcef10.webp b/TRELLIS.2/assets/example_image/5c80e5e03a3b60b6f03eaf555ba1dafc0e4230c472d7e8c8e2c5ca0a0dfcef10.webp
new file mode 100644
index 0000000000000000000000000000000000000000..7a10d813fb288d647e49f2b8bb2f5cdf578f873d
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/5c80e5e03a3b60b6f03eaf555ba1dafc0e4230c472d7e8c8e2c5ca0a0dfcef10.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fbd98cf5da79c56f8efc6cf86804391e71bdad2e935d21a7262472653a0674dc
+size 126914
diff --git a/TRELLIS.2/assets/example_image/61fea9d08e0bd9a067c9f696621dc89165afb5aab318d0701bc025d7863dabf0.webp b/TRELLIS.2/assets/example_image/61fea9d08e0bd9a067c9f696621dc89165afb5aab318d0701bc025d7863dabf0.webp
new file mode 100644
index 0000000000000000000000000000000000000000..021980a74ef652ae55bef0272527aab211275753
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/61fea9d08e0bd9a067c9f696621dc89165afb5aab318d0701bc025d7863dabf0.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dfad86b88eb81da36a5acf77891822c042e991436bb004c7d75d8b19e89c45bd
+size 110562
diff --git a/TRELLIS.2/assets/example_image/65433d02fc56dae164719ec29cb9646c0383aa1d0e24f0bb592899f08428d68e.webp b/TRELLIS.2/assets/example_image/65433d02fc56dae164719ec29cb9646c0383aa1d0e24f0bb592899f08428d68e.webp
new file mode 100644
index 0000000000000000000000000000000000000000..3fe995897ad1712af150b391a5d91063c3e417b5
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/65433d02fc56dae164719ec29cb9646c0383aa1d0e24f0bb592899f08428d68e.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fd73dcc5ae5b42a442c87f1522f370869f3d2e63922e6ecf769fd90fdeed1e66
+size 124876
diff --git a/TRELLIS.2/assets/example_image/6b6d89d46d7f53e6409dbe695a9ef8f97c5257e641da35015a78579e903acdad.webp b/TRELLIS.2/assets/example_image/6b6d89d46d7f53e6409dbe695a9ef8f97c5257e641da35015a78579e903acdad.webp
new file mode 100644
index 0000000000000000000000000000000000000000..8f787a298a8ba70c64beff1ad88cc9b96d4d58b9
Binary files /dev/null and b/TRELLIS.2/assets/example_image/6b6d89d46d7f53e6409dbe695a9ef8f97c5257e641da35015a78579e903acdad.webp differ
diff --git a/TRELLIS.2/assets/example_image/74fe541e8c8eac8d0b5d8ba144307f6c07ed832cd19bf1d431c74292002028cd.webp b/TRELLIS.2/assets/example_image/74fe541e8c8eac8d0b5d8ba144307f6c07ed832cd19bf1d431c74292002028cd.webp
new file mode 100644
index 0000000000000000000000000000000000000000..54a78c84746298a677529c8abe5858d6d734bbe7
Binary files /dev/null and b/TRELLIS.2/assets/example_image/74fe541e8c8eac8d0b5d8ba144307f6c07ed832cd19bf1d431c74292002028cd.webp differ
diff --git a/TRELLIS.2/assets/example_image/799ab13a23fe319a6876b8bf48007d0374d514f5e7aa31210e9b2cecfbace082.webp b/TRELLIS.2/assets/example_image/799ab13a23fe319a6876b8bf48007d0374d514f5e7aa31210e9b2cecfbace082.webp
new file mode 100644
index 0000000000000000000000000000000000000000..31b50241ad8cc38c4d2b9a00b36dc258dc172b73
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/799ab13a23fe319a6876b8bf48007d0374d514f5e7aa31210e9b2cecfbace082.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d0dd605ac2927b56f6ba5ced2d0b56aaba1be9f7dc2ab7f8d558d0f37856f6b5
+size 169830
diff --git a/TRELLIS.2/assets/example_image/7b540da337f576ffce2adc36c7459b9bbbfd845ab2160a6abbe986f1f906f6cd.webp b/TRELLIS.2/assets/example_image/7b540da337f576ffce2adc36c7459b9bbbfd845ab2160a6abbe986f1f906f6cd.webp
new file mode 100644
index 0000000000000000000000000000000000000000..b7a521fcdb71be9f5b095bd0c2a3a8b3ed9a32fc
Binary files /dev/null and b/TRELLIS.2/assets/example_image/7b540da337f576ffce2adc36c7459b9bbbfd845ab2160a6abbe986f1f906f6cd.webp differ
diff --git a/TRELLIS.2/assets/example_image/7baa867b4790b8596ee120f9b171b727fd9428c41980577a518505507c99d8a0.webp b/TRELLIS.2/assets/example_image/7baa867b4790b8596ee120f9b171b727fd9428c41980577a518505507c99d8a0.webp
new file mode 100644
index 0000000000000000000000000000000000000000..51557cf27478f8c301978278157bf71c1d4069f1
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/7baa867b4790b8596ee120f9b171b727fd9428c41980577a518505507c99d8a0.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41fd0f2a1cd66f4615a3947b6fdbddf527d4d628935a6fd208ca32a3b46849b1
+size 111992
diff --git a/TRELLIS.2/assets/example_image/7bd0521d20ee4805d1462a0ffb7d9aacc15180c2b741c9ac42a0d82ad3d340cb.webp b/TRELLIS.2/assets/example_image/7bd0521d20ee4805d1462a0ffb7d9aacc15180c2b741c9ac42a0d82ad3d340cb.webp
new file mode 100644
index 0000000000000000000000000000000000000000..b07990950bc8f3aee982664d6fd1264570906752
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/7bd0521d20ee4805d1462a0ffb7d9aacc15180c2b741c9ac42a0d82ad3d340cb.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b5a7835a908470c1142678cddfbfbe093ba0ec1085852ed072ae597f1eae5c37
+size 111836
diff --git a/TRELLIS.2/assets/example_image/7d585a8475db078593486367d98b5efa9368a60a3528c555b96026a1a674aa54.webp b/TRELLIS.2/assets/example_image/7d585a8475db078593486367d98b5efa9368a60a3528c555b96026a1a674aa54.webp
new file mode 100644
index 0000000000000000000000000000000000000000..5f10f35ab7a6f2d1d95d40e82c4bb91e30f165b5
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/7d585a8475db078593486367d98b5efa9368a60a3528c555b96026a1a674aa54.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7807391ef76523dab937bfcae5f9fc4803a65b86ab49310c17df0714288b7c48
+size 195232
diff --git a/TRELLIS.2/assets/example_image/7d6f4da4eafcc60243daf6ed210853df394a8bad7e701cadf551e21abcc77869.webp b/TRELLIS.2/assets/example_image/7d6f4da4eafcc60243daf6ed210853df394a8bad7e701cadf551e21abcc77869.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ab02dea2e3abcb802b48c82d6e7d670783f1be5e
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/7d6f4da4eafcc60243daf6ed210853df394a8bad7e701cadf551e21abcc77869.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3977e4b323080e122ec297f2fafe1203e717fef8417e82b6ed523e8438f829c6
+size 191642
diff --git a/TRELLIS.2/assets/example_image/7d7659d5943e85a73a4ffe33c6dd48f5d79601e9bf11b103516f419ce9fbf713.webp b/TRELLIS.2/assets/example_image/7d7659d5943e85a73a4ffe33c6dd48f5d79601e9bf11b103516f419ce9fbf713.webp
new file mode 100644
index 0000000000000000000000000000000000000000..60dd646a277d93fb76441ec47f88e22c4cf6967a
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/7d7659d5943e85a73a4ffe33c6dd48f5d79601e9bf11b103516f419ce9fbf713.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6707893380d3c791a9a2d33bc0caa5f10719f7168d25f8d447fa26f4420919db
+size 108942
diff --git a/TRELLIS.2/assets/example_image/80ad7988fc2ce62fc655b21a8950865566ec3f5a8b4398f2502db6414a3e6834.webp b/TRELLIS.2/assets/example_image/80ad7988fc2ce62fc655b21a8950865566ec3f5a8b4398f2502db6414a3e6834.webp
new file mode 100644
index 0000000000000000000000000000000000000000..3d6c84ab1ccc878d9f292a04b579642b92c14fc9
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/80ad7988fc2ce62fc655b21a8950865566ec3f5a8b4398f2502db6414a3e6834.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9558307682a1e723f86291af377f0b53970c0d301304c1f43dec741fedc209d7
+size 117870
diff --git a/TRELLIS.2/assets/example_image/8aa698c59aab48d4ce69a558d9159107890e3d64e522af404d9635ad0be21f88.webp b/TRELLIS.2/assets/example_image/8aa698c59aab48d4ce69a558d9159107890e3d64e522af404d9635ad0be21f88.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f12cbf93875f086f3084efc29072f8fb579f3143
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/8aa698c59aab48d4ce69a558d9159107890e3d64e522af404d9635ad0be21f88.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a319ace2549835da92a6ffa5db73eebd7fce29079e5865cb32dfbdac21d9b900
+size 100414
diff --git a/TRELLIS.2/assets/example_image/8ce83f6a28910e755902de10918672e77dd23476f43f0f1521c48667de6cea84.webp b/TRELLIS.2/assets/example_image/8ce83f6a28910e755902de10918672e77dd23476f43f0f1521c48667de6cea84.webp
new file mode 100644
index 0000000000000000000000000000000000000000..afc4b658a9e2dfefd67a66e91cf60f009b74e8bd
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/8ce83f6a28910e755902de10918672e77dd23476f43f0f1521c48667de6cea84.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5b8373ce90506089d23907895d7efac4c37defb603ea7434bee9c4de870bf7da
+size 179774
diff --git a/TRELLIS.2/assets/example_image/8e12cf0977c0476396e7112f04b73d4d73569421173fcb553213d45030bddec3.webp b/TRELLIS.2/assets/example_image/8e12cf0977c0476396e7112f04b73d4d73569421173fcb553213d45030bddec3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..d4298ffbb33598e6bb6392741f65cc9bc648a468
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/8e12cf0977c0476396e7112f04b73d4d73569421173fcb553213d45030bddec3.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:643b3d426830d89dc62634027f802e3af5450eb45591eeb413ae67d5ba56f557
+size 114408
diff --git a/TRELLIS.2/assets/example_image/901d8de4c2011a8502a0decd0adec0fc7418f26165cd52ced64fd44f720353ef.webp b/TRELLIS.2/assets/example_image/901d8de4c2011a8502a0decd0adec0fc7418f26165cd52ced64fd44f720353ef.webp
new file mode 100644
index 0000000000000000000000000000000000000000..bbd93cd629c4850d0ddfcd65763478d1897cbb1c
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/901d8de4c2011a8502a0decd0adec0fc7418f26165cd52ced64fd44f720353ef.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d4e65a295b78ca3505337eb1cc58d0e5ff7effc0d500d01e503c4d5243af0a68
+size 103346
diff --git a/TRELLIS.2/assets/example_image/95db3c13622788ec311ae4dfa24dd88732c66ca5e340a0bf3465d2a528204037.webp b/TRELLIS.2/assets/example_image/95db3c13622788ec311ae4dfa24dd88732c66ca5e340a0bf3465d2a528204037.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a0795fe45f2477d4811a07bd2168f08ef9460960
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/95db3c13622788ec311ae4dfa24dd88732c66ca5e340a0bf3465d2a528204037.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:23b3f7294731c66a3a9db7ccbd593708e1ba56819cff970b29fd9fbf286588e0
+size 187208
diff --git a/TRELLIS.2/assets/example_image/9c306c7bd0e857285f536fb500c0828e5fad4e23c3ceeab92c888c568fa19101.webp b/TRELLIS.2/assets/example_image/9c306c7bd0e857285f536fb500c0828e5fad4e23c3ceeab92c888c568fa19101.webp
new file mode 100644
index 0000000000000000000000000000000000000000..b668a21a0f5e8a3c0730377da02357cd6e30b869
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/9c306c7bd0e857285f536fb500c0828e5fad4e23c3ceeab92c888c568fa19101.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0d42562b49df17554583f2acbe18f8a26c9075cdab278caefab27aa7587df4ac
+size 115424
diff --git a/TRELLIS.2/assets/example_image/T.png b/TRELLIS.2/assets/example_image/T.png
new file mode 100644
index 0000000000000000000000000000000000000000..171f72e68f117c7d2507f94970a6a8d2d5e7e563
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/T.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:db468bad8a04f1474a8d68140c07501b013b3ec6124b911fb7852675d64c05ee
+size 1718470
diff --git a/TRELLIS.2/assets/example_image/a13d176cd7a7d457b42d1b32223bcff1a45dafbbb42c6a272b97d65ac2f2eb52.webp b/TRELLIS.2/assets/example_image/a13d176cd7a7d457b42d1b32223bcff1a45dafbbb42c6a272b97d65ac2f2eb52.webp
new file mode 100644
index 0000000000000000000000000000000000000000..7f764c337d834d1077aef043aa277f360b20d9ba
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/a13d176cd7a7d457b42d1b32223bcff1a45dafbbb42c6a272b97d65ac2f2eb52.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:94b508edb4a3c49ff4e5c4c583b6980a7d0ef84a2f16a301ac9b671d421b8a52
+size 103072
diff --git a/TRELLIS.2/assets/example_image/a306e2ee5cbc3da45e7db48d75a0cade0bb7eee263a74bc6820c617afaba1302.webp b/TRELLIS.2/assets/example_image/a306e2ee5cbc3da45e7db48d75a0cade0bb7eee263a74bc6820c617afaba1302.webp
new file mode 100644
index 0000000000000000000000000000000000000000..e4cf1566ad8daa3be8f938d3d3e5b00b297c7414
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/a306e2ee5cbc3da45e7db48d75a0cade0bb7eee263a74bc6820c617afaba1302.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:71c2035d7968538b51a5edb0d853a310f3f03b9626b705ac7f14398bb72f6093
+size 101638
diff --git a/TRELLIS.2/assets/example_image/a3d0c28c7d9c6f23adb941c4def2523572c903a94469abcaa7dd1398d28af8f1.webp b/TRELLIS.2/assets/example_image/a3d0c28c7d9c6f23adb941c4def2523572c903a94469abcaa7dd1398d28af8f1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..29b7868f213043532468e2fa1c169c3a9c98ce26
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/a3d0c28c7d9c6f23adb941c4def2523572c903a94469abcaa7dd1398d28af8f1.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7a8dbf4af05a60591cb157bcbb19c58c05c1d5622aaecddaf5aaabf292e89ea0
+size 208094
diff --git a/TRELLIS.2/assets/example_image/a63d2595e10229067b19cb167fe2bdc152dabfd8b62ae45fc1655a4cf66509bc.webp b/TRELLIS.2/assets/example_image/a63d2595e10229067b19cb167fe2bdc152dabfd8b62ae45fc1655a4cf66509bc.webp
new file mode 100644
index 0000000000000000000000000000000000000000..242c31ce26348b99d98a69f789cf646ca472db05
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/a63d2595e10229067b19cb167fe2bdc152dabfd8b62ae45fc1655a4cf66509bc.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b3786b5f2c6715d02a20abde45f4465883eb8b791a807f9dfc86dc78a17b7c58
+size 180294
diff --git a/TRELLIS.2/assets/example_image/ab3bb3e183991253ae66c06d44dc6105f3c113a1a1f819ab57a93c6f60b0d32b.webp b/TRELLIS.2/assets/example_image/ab3bb3e183991253ae66c06d44dc6105f3c113a1a1f819ab57a93c6f60b0d32b.webp
new file mode 100644
index 0000000000000000000000000000000000000000..00790a403686c1fb1a78e30b9e0bad269dcb80a6
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/ab3bb3e183991253ae66c06d44dc6105f3c113a1a1f819ab57a93c6f60b0d32b.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:69f3ab098a28bf0c06194ab523ba10e30ce3db331871e2e8fa97cfd5967853b0
+size 180186
diff --git a/TRELLIS.2/assets/example_image/b205f4483c47bd1fec8e229163361e4fdff9f77923c5e968343b8f1dd76b61dc.webp b/TRELLIS.2/assets/example_image/b205f4483c47bd1fec8e229163361e4fdff9f77923c5e968343b8f1dd76b61dc.webp
new file mode 100644
index 0000000000000000000000000000000000000000..dc0630884d160addf2997b2435fd15ea3bece805
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/b205f4483c47bd1fec8e229163361e4fdff9f77923c5e968343b8f1dd76b61dc.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cc3d5f2d5228c9314d8037105cc24798499aea1aaf311cde332df74d17f96da6
+size 130468
diff --git a/TRELLIS.2/assets/example_image/b358d0eb96a68ac4ba1f2fb6d44ea2225f95fdfbf9cf4e0da08650c3704f1d23.webp b/TRELLIS.2/assets/example_image/b358d0eb96a68ac4ba1f2fb6d44ea2225f95fdfbf9cf4e0da08650c3704f1d23.webp
new file mode 100644
index 0000000000000000000000000000000000000000..cfa8a87a3b0c0a5ed90f249c030815517317403c
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/b358d0eb96a68ac4ba1f2fb6d44ea2225f95fdfbf9cf4e0da08650c3704f1d23.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a77a4ab99beb302c5934efaeaeef2effc48b2c07b9d68cadb06d68396a48abea
+size 106998
diff --git a/TRELLIS.2/assets/example_image/bb3190891dd8341c9d6d3d4faa6525c6ecdac19945526904928f6bcd2f3f45f1.webp b/TRELLIS.2/assets/example_image/bb3190891dd8341c9d6d3d4faa6525c6ecdac19945526904928f6bcd2f3f45f1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..9b23b87c2a30e9c704de86bc7c2214a9629661a8
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/bb3190891dd8341c9d6d3d4faa6525c6ecdac19945526904928f6bcd2f3f45f1.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:01962bf62febbf916100201f915d27ab881c747a9e283228d8b9c890c1eb2fb8
+size 155612
diff --git a/TRELLIS.2/assets/example_image/be7deb26f4fdd2080d4288668af4c39e526564282c579559ff8a4126ca4ed6c1.webp b/TRELLIS.2/assets/example_image/be7deb26f4fdd2080d4288668af4c39e526564282c579559ff8a4126ca4ed6c1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4ae373686902684181a5f7c84f976a02f3fea9d5
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/be7deb26f4fdd2080d4288668af4c39e526564282c579559ff8a4126ca4ed6c1.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ed898f0689bd19f163fbfb601b9c9d31c422ab2ad409ec07f61b70471636c164
+size 155628
diff --git a/TRELLIS.2/assets/example_image/c2125d086c2529638841f38918ae1defbf33e6796d827253885b4c51e601034f.webp b/TRELLIS.2/assets/example_image/c2125d086c2529638841f38918ae1defbf33e6796d827253885b4c51e601034f.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4282564790b1a57ea1d4a7c2f77dd84775cade17
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/c2125d086c2529638841f38918ae1defbf33e6796d827253885b4c51e601034f.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:961adcb3c9c10db565957bfcf5d0be49e18c23012363a78bebcf8b49dbd7153c
+size 206140
diff --git a/TRELLIS.2/assets/example_image/c3d714bc125f06ce1187799d5ca10736b4064a24c141e627089aad2bdedf7aa5.webp b/TRELLIS.2/assets/example_image/c3d714bc125f06ce1187799d5ca10736b4064a24c141e627089aad2bdedf7aa5.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4203f61711b705c5e5e0e6f49e52f9b555c878a9
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/c3d714bc125f06ce1187799d5ca10736b4064a24c141e627089aad2bdedf7aa5.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e211aff13d1e7dcdf592d68ea34e03794c4464c5b159224d7c508d9ecae5eb59
+size 151940
diff --git a/TRELLIS.2/assets/example_image/c9340e744541f310bf89838f652602961d3e5950b31cd349bcbfc7e59e15cd2e.webp b/TRELLIS.2/assets/example_image/c9340e744541f310bf89838f652602961d3e5950b31cd349bcbfc7e59e15cd2e.webp
new file mode 100644
index 0000000000000000000000000000000000000000..fc11f391f770d92966ef73037c8769f807337875
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/c9340e744541f310bf89838f652602961d3e5950b31cd349bcbfc7e59e15cd2e.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4533ce41604e7aff386c71f37f0b2727242a4615ef0e37c3cd62273678ad1809
+size 142682
diff --git a/TRELLIS.2/assets/example_image/cd3c309f17eee5ad6afe4e001765893ade20b653f611365c93d158286b4cee96.webp b/TRELLIS.2/assets/example_image/cd3c309f17eee5ad6afe4e001765893ade20b653f611365c93d158286b4cee96.webp
new file mode 100644
index 0000000000000000000000000000000000000000..898e801ef377765e4082aa5968db56dd6e696a06
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/cd3c309f17eee5ad6afe4e001765893ade20b653f611365c93d158286b4cee96.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ec6060536a5db96092d419be6e0f9d14985f6954ced1605e9d473d415ff29368
+size 764638
diff --git a/TRELLIS.2/assets/example_image/cdf996a6cc218918eeb90209891ce306a230e6d9cca2a3d9bbb37c6d7b6bd318.webp b/TRELLIS.2/assets/example_image/cdf996a6cc218918eeb90209891ce306a230e6d9cca2a3d9bbb37c6d7b6bd318.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6d79bbc33c14ba034cbc6f5dc7ab443e0f92d445
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/cdf996a6cc218918eeb90209891ce306a230e6d9cca2a3d9bbb37c6d7b6bd318.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eaf705e6205f5101af261fac1a3477121cf377f92ff93feaf506eada70de98d7
+size 217676
diff --git a/TRELLIS.2/assets/example_image/d39c2bd426456bd686de33f924524d18eb47343a5f080826aa3cb8e77de5147b.webp b/TRELLIS.2/assets/example_image/d39c2bd426456bd686de33f924524d18eb47343a5f080826aa3cb8e77de5147b.webp
new file mode 100644
index 0000000000000000000000000000000000000000..66bc8713ed9f5a86463850a3dd130f6d9a4953c0
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/d39c2bd426456bd686de33f924524d18eb47343a5f080826aa3cb8e77de5147b.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8c0c09536a1a6c1c44e7c8649b1fda58ed4404ffa26debdc6f1719aaa7fdc59b
+size 235370
diff --git a/TRELLIS.2/assets/example_image/d64c94dffdadf82d46004d11412b5a3b2a17f1b4ddb428477a7ba38652adf973.webp b/TRELLIS.2/assets/example_image/d64c94dffdadf82d46004d11412b5a3b2a17f1b4ddb428477a7ba38652adf973.webp
new file mode 100644
index 0000000000000000000000000000000000000000..2573d75a2a428aef7d4d42daaa29d087b293a461
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/d64c94dffdadf82d46004d11412b5a3b2a17f1b4ddb428477a7ba38652adf973.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:373afe2a56a038d1356f3fc5f1c8fb04778e90cb2216ad1c60ba7e2d2877705f
+size 153922
diff --git a/TRELLIS.2/assets/example_image/dd4c51c13a996b9eec9c954a45cd5cd457059bf9f030aadde48d88225a9f3321.webp b/TRELLIS.2/assets/example_image/dd4c51c13a996b9eec9c954a45cd5cd457059bf9f030aadde48d88225a9f3321.webp
new file mode 100644
index 0000000000000000000000000000000000000000..65b852da0703baeaee573de95f33b9ce366731d8
Binary files /dev/null and b/TRELLIS.2/assets/example_image/dd4c51c13a996b9eec9c954a45cd5cd457059bf9f030aadde48d88225a9f3321.webp differ
diff --git a/TRELLIS.2/assets/example_image/e10465728ebea1e055524f97ac5d47cebf82a672f07a05409aa07d826c9d9f37.webp b/TRELLIS.2/assets/example_image/e10465728ebea1e055524f97ac5d47cebf82a672f07a05409aa07d826c9d9f37.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a773e5c7e9a3e0078acdf30dbace00de6e22cd18
Binary files /dev/null and b/TRELLIS.2/assets/example_image/e10465728ebea1e055524f97ac5d47cebf82a672f07a05409aa07d826c9d9f37.webp differ
diff --git a/TRELLIS.2/assets/example_image/e134444178eae855cfdefb9e5259d076df5e34f780ee44d4ad604483ff69cc74.webp b/TRELLIS.2/assets/example_image/e134444178eae855cfdefb9e5259d076df5e34f780ee44d4ad604483ff69cc74.webp
new file mode 100644
index 0000000000000000000000000000000000000000..9ffe4be1a5349b8a65b220b6063386831816db4b
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/e134444178eae855cfdefb9e5259d076df5e34f780ee44d4ad604483ff69cc74.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:309713c97b32a579a232faea918aea7c49d3638b07c47f29072523bb4e95c5a0
+size 167178
diff --git a/TRELLIS.2/assets/example_image/e3c57169ce3d5ce10b3c10acef20b81ca774b54a17aabe74e8aca320c7b07b55.webp b/TRELLIS.2/assets/example_image/e3c57169ce3d5ce10b3c10acef20b81ca774b54a17aabe74e8aca320c7b07b55.webp
new file mode 100644
index 0000000000000000000000000000000000000000..335531a6f0d695d3463e0bbfc478c08ad19c93ed
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/e3c57169ce3d5ce10b3c10acef20b81ca774b54a17aabe74e8aca320c7b07b55.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:15e90c0ce28673b896e754ca56060dd840799cb8b95fb4ebeb06661675f8ed07
+size 182650
diff --git a/TRELLIS.2/assets/example_image/e4d6b2f3a18c3e0f5146a5b40cda6c95d7f69372b2e741c023e5ec9661deda2b.webp b/TRELLIS.2/assets/example_image/e4d6b2f3a18c3e0f5146a5b40cda6c95d7f69372b2e741c023e5ec9661deda2b.webp
new file mode 100644
index 0000000000000000000000000000000000000000..114d6ffaa3545023654eea953aee8c22031e40a1
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/e4d6b2f3a18c3e0f5146a5b40cda6c95d7f69372b2e741c023e5ec9661deda2b.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05a0cabaea29f4d03c6468d039fe09af8eb8c3647952f3bcb342421445ea00a2
+size 229896
diff --git a/TRELLIS.2/assets/example_image/e513fcd6c897b249fc4bff54268b4d0bbab6403503ecf3846d92feb892536e5e.webp b/TRELLIS.2/assets/example_image/e513fcd6c897b249fc4bff54268b4d0bbab6403503ecf3846d92feb892536e5e.webp
new file mode 100644
index 0000000000000000000000000000000000000000..e64acdec6e24981b82c80f35bafb44766ac6cc31
Binary files /dev/null and b/TRELLIS.2/assets/example_image/e513fcd6c897b249fc4bff54268b4d0bbab6403503ecf3846d92feb892536e5e.webp differ
diff --git a/TRELLIS.2/assets/example_image/ebd09565cf0b6593aced573dffdfff34915aa359c60ec5dd0b30cd91a7f153c8.webp b/TRELLIS.2/assets/example_image/ebd09565cf0b6593aced573dffdfff34915aa359c60ec5dd0b30cd91a7f153c8.webp
new file mode 100644
index 0000000000000000000000000000000000000000..08850da10b51022be1509076a797e4b4ea2887a1
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/ebd09565cf0b6593aced573dffdfff34915aa359c60ec5dd0b30cd91a7f153c8.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:477c0c9ef774e796a27645e1c143e7bd8d574cb6f31f2a0a9f57aaf66e80c0be
+size 106434
diff --git a/TRELLIS.2/assets/example_image/ee8ecf658fde9c58830c021b2e30d0d5e7e492ef52febe7192a6c74fbf1b0472.webp b/TRELLIS.2/assets/example_image/ee8ecf658fde9c58830c021b2e30d0d5e7e492ef52febe7192a6c74fbf1b0472.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ba44a2d028fc04d8b74cef6935f8db9e9df17ce5
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/ee8ecf658fde9c58830c021b2e30d0d5e7e492ef52febe7192a6c74fbf1b0472.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b169654d84f98e808a875bc80b47e0cfe988af495250dba4368edf3eea4f633
+size 304284
diff --git a/TRELLIS.2/assets/example_image/f351569ddc61116da4a7b929bccdab144d011f56b9603e6e72abea05236160f4.webp b/TRELLIS.2/assets/example_image/f351569ddc61116da4a7b929bccdab144d011f56b9603e6e72abea05236160f4.webp
new file mode 100644
index 0000000000000000000000000000000000000000..b9e06fd37eba38547fe24b88ce68c442086a83c7
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/f351569ddc61116da4a7b929bccdab144d011f56b9603e6e72abea05236160f4.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:242db48e9c2e6e45a888fdd24f133b966f460b583f1e77324252b869d1a7d65d
+size 254674
diff --git a/TRELLIS.2/assets/example_image/f5332118a0cda9cd13fe13d4be2b00437e702d1f9af51ebb6b75219a572a6ce9.webp b/TRELLIS.2/assets/example_image/f5332118a0cda9cd13fe13d4be2b00437e702d1f9af51ebb6b75219a572a6ce9.webp
new file mode 100644
index 0000000000000000000000000000000000000000..16921f8bf9843166dd1e7695fcb5fa13008c75e1
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/f5332118a0cda9cd13fe13d4be2b00437e702d1f9af51ebb6b75219a572a6ce9.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6f669f15496ecc1f3ec9819b40c8ca46ce2c080f49eab342724f2872f5c9dcff
+size 186202
diff --git a/TRELLIS.2/assets/example_image/f8920788b704531f7a7e875afd7c5c423d62e0a987e9495c63893c2cb4d2b5dc.webp b/TRELLIS.2/assets/example_image/f8920788b704531f7a7e875afd7c5c423d62e0a987e9495c63893c2cb4d2b5dc.webp
new file mode 100644
index 0000000000000000000000000000000000000000..c2ab696162c9dae5f90114d4825af5ec30cb28cb
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/f8920788b704531f7a7e875afd7c5c423d62e0a987e9495c63893c2cb4d2b5dc.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f4d093a8f99f3fc25a588785ceee95180427ff8dd063e2fda9f1e7f41cf40940
+size 247040
diff --git a/TRELLIS.2/assets/example_image/f8a7eafe26a4f3ebd26a9e7d0289e4a40b5a93e9234e94ec3e1071c352acc65a.webp b/TRELLIS.2/assets/example_image/f8a7eafe26a4f3ebd26a9e7d0289e4a40b5a93e9234e94ec3e1071c352acc65a.webp
new file mode 100644
index 0000000000000000000000000000000000000000..1ae36239b3659bf579bd2588f930cdcd02d68b13
--- /dev/null
+++ b/TRELLIS.2/assets/example_image/f8a7eafe26a4f3ebd26a9e7d0289e4a40b5a93e9234e94ec3e1071c352acc65a.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0d65e9fdbe6e4b432e34fbae16ea8a3d98e3cef81a9b1613f294039e96805e77
+size 208356
diff --git a/TRELLIS.2/assets/example_image/f94e2b76494ce2cf1874611273e5fb3d76b395793bb5647492fa85c2ce0a248b.webp b/TRELLIS.2/assets/example_image/f94e2b76494ce2cf1874611273e5fb3d76b395793bb5647492fa85c2ce0a248b.webp
new file mode 100644
index 0000000000000000000000000000000000000000..9c24d0eb0a3d0c2c7ddc69e3ae39f4e9d85b9243
Binary files /dev/null and b/TRELLIS.2/assets/example_image/f94e2b76494ce2cf1874611273e5fb3d76b395793bb5647492fa85c2ce0a248b.webp differ
diff --git a/TRELLIS.2/assets/example_image/fdf979f5227f24b554fca28aa71c351beb7b1be2be236b50bbe07f59e9b8a50c.webp b/TRELLIS.2/assets/example_image/fdf979f5227f24b554fca28aa71c351beb7b1be2be236b50bbe07f59e9b8a50c.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f90db415387320470e55cc5bdcf62635e7b45726
Binary files /dev/null and b/TRELLIS.2/assets/example_image/fdf979f5227f24b554fca28aa71c351beb7b1be2be236b50bbe07f59e9b8a50c.webp differ
diff --git a/TRELLIS.2/assets/hdri/city.exr b/TRELLIS.2/assets/hdri/city.exr
new file mode 100644
index 0000000000000000000000000000000000000000..fac69a5403a2a3b51d725bca679174d2f0208b25
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/city.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e42abcd2fa3231e5c2485ca6dd64800534d157b7194ab7fe9cc3bf5a56d0256
+size 204863
diff --git a/TRELLIS.2/assets/hdri/courtyard.exr b/TRELLIS.2/assets/hdri/courtyard.exr
new file mode 100644
index 0000000000000000000000000000000000000000..142504138fb47eba3024495d69923211ebeda9b0
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/courtyard.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6690b47725965531559380121e6878373eb599655e35fefd109a4bd0911366f3
+size 255126
diff --git a/TRELLIS.2/assets/hdri/forest.exr b/TRELLIS.2/assets/hdri/forest.exr
new file mode 100644
index 0000000000000000000000000000000000000000..7809de1141fe935457de0cc73d8fe87ecf924e1a
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/forest.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bdf2298244affa0f85509380fd130ac6d4dfaa3c856df065998f7f4c1a93dc0d
+size 552641
diff --git a/TRELLIS.2/assets/hdri/interior.exr b/TRELLIS.2/assets/hdri/interior.exr
new file mode 100644
index 0000000000000000000000000000000000000000..ddb91daa8b222bedea152d60221499768d0e0fd7
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/interior.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e945ff5c1ddd7a3aaf05e9fb5c3bc9cb93c5518414febd44ed2c394e013f0cbd
+size 189416
diff --git a/TRELLIS.2/assets/hdri/license.txt b/TRELLIS.2/assets/hdri/license.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eba5cb8037c9eb45e8c8638c99b39f7160a69214
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/license.txt
@@ -0,0 +1,15 @@
+All HDRIs are licensed as CC0.
+
+These were created by Greg Zaal (Poly Haven https://polyhaven.com).
+Originals used for each HDRI:
+- City: https://polyhaven.com/a/portland_landing_pad
+- Courtyard: https://polyhaven.com/a/courtyard
+- Forest: https://polyhaven.com/a/ninomaru_teien
+- Interior: https://polyhaven.com/a/hotel_room
+- Night: Probably https://polyhaven.com/a/moonless_golf
+- Studio: Probably https://polyhaven.com/a/studio_small_01
+- Sunrise: https://polyhaven.com/a/spruit_sunrise
+- Sunset: https://polyhaven.com/a/venice_sunset
+
+1K resolution of each was taken, and compressed with oiiotool:
+oiiotool input.exr --ch R,G,B -d float --compression dwab:300 --clamp:min=0.0:max=32000.0 -o output.exr
diff --git a/TRELLIS.2/assets/hdri/night.exr b/TRELLIS.2/assets/hdri/night.exr
new file mode 100644
index 0000000000000000000000000000000000000000..380591f26bebbd1419b703145dedb20cab765f59
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/night.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:17480af5547465d160f7307c92585cf30820ca563f87f066395decbad8ac32a4
+size 139959
diff --git a/TRELLIS.2/assets/hdri/studio.exr b/TRELLIS.2/assets/hdri/studio.exr
new file mode 100644
index 0000000000000000000000000000000000000000..baf478da00acddbd70593e36d90146eb15c8939d
Binary files /dev/null and b/TRELLIS.2/assets/hdri/studio.exr differ
diff --git a/TRELLIS.2/assets/hdri/sunrise.exr b/TRELLIS.2/assets/hdri/sunrise.exr
new file mode 100644
index 0000000000000000000000000000000000000000..b0689a58e51c6527ed8810186644dd482f96799a
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/sunrise.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a1180126e4db7d01f134c5430ea43c1b263ab1a12faf58a444d9ce9c03f3a84
+size 251877
diff --git a/TRELLIS.2/assets/hdri/sunset.exr b/TRELLIS.2/assets/hdri/sunset.exr
new file mode 100644
index 0000000000000000000000000000000000000000..bf0414b39faf538b48baa62257aa6e5ff168928f
--- /dev/null
+++ b/TRELLIS.2/assets/hdri/sunset.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3bcafdda4f2d7b9759cc1d73004d34d721a274c29b1a0947be88a602dbac426b
+size 171164
diff --git a/TRELLIS.2/autotune_cache.json b/TRELLIS.2/autotune_cache.json
new file mode 100644
index 0000000000000000000000000000000000000000..3936f3b5609088d84c05ca1dbfa4841af607a897
--- /dev/null
+++ b/TRELLIS.2/autotune_cache.json
@@ -0,0 +1,24360 @@
+{
+ "*": {
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm.sparse_submanifold_conv_bwd_input_implicit_gemm_kernel": {
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm.sparse_submanifold_conv_bwd_weight_implicit_gemm_kernel": {
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_implicit_gemm_kernel": {
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_implicit_gemm_kernel": {
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_implicit_gemm_splitk_kernel": {
+ "(7, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_implicit_gemm_splitk_kernel": {
+ "(7, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_implicit_gemm_splitk": {
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 1
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_implicit_gemm_splitk": {
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 8
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm.sparse_submanifold_conv_bwd_input_masked_implicit_gemm_kernel": {
+ "(18, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm.sparse_submanifold_conv_bwd_weight_masked_implicit_gemm_kernel": {
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_masked_implicit_gemm_kernel": {
+ "(18, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_masked_implicit_gemm_kernel": {
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_masked_implicit_gemm_splitk_kernel": {
+ "(16, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_masked_implicit_gemm_splitk_kernel": {
+ "(18, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.uint32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_input_masked_implicit_gemm_splitk": {
+ "(2^18, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 1024, 27)": {
+ "SPLITK": 2
+ },
+ "(2^14, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 512, 2048, 27)": {
+ "SPLITK": 4
+ },
+ "(2^12, 512, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^10, 1024, 4096, 27)": {
+ "SPLITK": 8
+ },
+ "(2^10, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^12, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 512, 2048, 27)": {
+ "SPLITK": 8
+ },
+ "(2^11, 512, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^9, 1024, 4096, 27)": {
+ "SPLITK": 16
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^11, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^8, 1024, 4096, 27)": {
+ "SPLITK": 16
+ },
+ "(2^8, 1024, 1024, 27)": {
+ "SPLITK": 16
+ },
+ "(2^19, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 1024, 27)": {
+ "SPLITK": 2
+ },
+ "(2^15, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 2048, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 1024, 4096, 27)": {
+ "SPLITK": 16
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^10, 512, 2048, 27)": {
+ "SPLITK": 16
+ },
+ "(2^10, 512, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^10, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^12, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 512, 2048, 27)": {
+ "SPLITK": 4
+ },
+ "(2^14, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^7, 1024, 4096, 27)": {
+ "SPLITK": 32
+ },
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^14, 128, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^14, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_bwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_bwd_weight_masked_implicit_gemm_splitk": {
+ "(2^18, 64, 64, 27)": {
+ "SPLITK": 128
+ },
+ "(2^16, 128, 512, 27)": {
+ "SPLITK": 16
+ },
+ "(2^16, 128, 128, 27)": {
+ "SPLITK": 32
+ },
+ "(2^14, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 256, 27)": {
+ "SPLITK": 4
+ },
+ "(2^12, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 64, 27)": {
+ "SPLITK": 16
+ },
+ "(2^16, 128, 32, 27)": {
+ "SPLITK": 64
+ },
+ "(2^18, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^11, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^9, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 256, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 256, 64, 27)": {
+ "SPLITK": 16
+ },
+ "(2^17, 64, 64, 27)": {
+ "SPLITK": 64
+ },
+ "(2^15, 128, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^15, 128, 128, 27)": {
+ "SPLITK": 16
+ },
+ "(2^15, 128, 32, 27)": {
+ "SPLITK": 32
+ },
+ "(2^17, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^8, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^8, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 64, 64, 27)": {
+ "SPLITK": 128
+ },
+ "(2^17, 128, 512, 27)": {
+ "SPLITK": 16
+ },
+ "(2^17, 128, 128, 27)": {
+ "SPLITK": 32
+ },
+ "(2^15, 256, 1024, 27)": {
+ "SPLITK": 2
+ },
+ "(2^15, 256, 256, 27)": {
+ "SPLITK": 8
+ },
+ "(2^13, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 64, 27)": {
+ "SPLITK": 8
+ },
+ "(2^17, 128, 32, 27)": {
+ "SPLITK": 64
+ },
+ "(2^19, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^11, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 64, 27)": {
+ "SPLITK": 128
+ },
+ "(2^20, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^18, 128, 512, 27)": {
+ "SPLITK": 32
+ },
+ "(2^18, 128, 128, 27)": {
+ "SPLITK": 64
+ },
+ "(2^18, 128, 32, 27)": {
+ "SPLITK": 64
+ },
+ "(2^16, 256, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^16, 256, 256, 27)": {
+ "SPLITK": 4
+ },
+ "(2^16, 256, 64, 27)": {
+ "SPLITK": 8
+ },
+ "(2^12, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 64, 27)": {
+ "SPLITK": 8
+ },
+ "(2^21, 64, 64, 27)": {
+ "SPLITK": 128
+ },
+ "(2^21, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^19, 128, 512, 27)": {
+ "SPLITK": 32
+ },
+ "(2^19, 128, 128, 27)": {
+ "SPLITK": 128
+ },
+ "(2^17, 256, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 8
+ },
+ "(2^14, 512, 2048, 27)": {
+ "SPLITK": 2
+ },
+ "(2^14, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 512, 128, 27)": {
+ "SPLITK": 4
+ },
+ "(2^17, 256, 64, 27)": {
+ "SPLITK": 32
+ },
+ "(2^19, 128, 32, 27)": {
+ "SPLITK": 128
+ },
+ "(2^7, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 128, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^14, 128, 128, 27)": {
+ "SPLITK": 16
+ },
+ "(2^14, 128, 32, 27)": {
+ "SPLITK": 32
+ },
+ "(2^16, 64, 64, 27)": {
+ "SPLITK": 32
+ },
+ "(2^16, 64, 16, 27)": {
+ "SPLITK": 64
+ },
+ "(2^22, 64, 64, 27)": {
+ "SPLITK": 8
+ },
+ "(2^22, 64, 16, 27)": {
+ "SPLITK": 128
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_implicit_gemm.sparse_submanifold_conv_fwd_implicit_gemm_kernel": {
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_implicit_gemm_splitk.sparse_submanifold_conv_fwd_implicit_gemm_kernel": {
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_implicit_gemm_splitk.sparse_submanifold_conv_fwd_implicit_gemm_splitk_kernel": {
+ "(8, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 16, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_implicit_gemm_splitk.sparse_submanifold_conv_fwd_implicit_gemm_splitk": {
+ "(2^8, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^10, 1024, 1024, 27)": {
+ "SPLITK": 2
+ },
+ "(2^12, 1024, 1024, 27)": {
+ "SPLITK": 2
+ },
+ "(2^14, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 16
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 128, 27)": {
+ "SPLITK": 1
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_masked_implicit_gemm.sparse_submanifold_conv_fwd_masked_implicit_gemm_kernel": {
+ "(18, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_fwd_masked_implicit_gemm_kernel": {
+ "(18, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 1024, 4096, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(21, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 256, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(19, 128, 128, 27, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 512, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(18, 512, 2048, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 256, 256, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(20, 256, 1024, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 128, 128, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 128, 512, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 64, 64, 27, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float16')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_fwd_masked_implicit_gemm_splitk_kernel": {
+ "(16, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 512, 2048, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 256, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 4096, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 128, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 64, 16, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 256, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 1024, 4096, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 512, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 512, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 256,
+ "BK": 64
+ },
+ "num_warps": 8,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 1024, 1024, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(16, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(17, 512, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(14, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(12, 128, 32, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(10, 256, 64, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 512, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 512, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(8, 512, 128, 27, 1024, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 16, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(15, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 128, 32, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 512, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 512, 128, 27, 512, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, 2, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(13, 64, 16, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 256,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 4, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 256, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 256, 64, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 8, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 16, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 32, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 64, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 128, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(6, 1024, 1024, 27, 256, True, 'torch.float16', 'torch.float16', 'torch.float16', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 64
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(7, 1024, 1024, 27, 4, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 64,
+ "B2": 64,
+ "BK": 64
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(9, 1024, 1024, 27, 8, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(11, 1024, 1024, 27, 4, True, 'torch.float32', 'torch.float32', 'torch.float32', 'torch.uint32', 'torch.int64', 'torch.float32')": {
+ "kwargs": {
+ "B1": 128,
+ "B2": 128,
+ "BK": 32
+ },
+ "num_warps": 4,
+ "num_ctas": 1,
+ "num_stages": 4,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ },
+ "flex_gemm.kernels.triton.spconv.sparse_submanifold_conv_fwd_masked_implicit_gemm_splitk.sparse_submanifold_conv_fwd_masked_implicit_gemm_splitk": {
+ "(2^18, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 512, 128, 27)": {
+ "SPLITK": 16
+ },
+ "(2^10, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^10, 1024, 4096, 27)": {
+ "SPLITK": 4
+ },
+ "(2^12, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 512, 27)": {
+ "SPLITK": 2
+ },
+ "(2^13, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^11, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 512, 512, 27)": {
+ "SPLITK": 4
+ },
+ "(2^11, 512, 128, 27)": {
+ "SPLITK": 16
+ },
+ "(2^9, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^9, 1024, 4096, 27)": {
+ "SPLITK": 8
+ },
+ "(2^11, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^8, 1024, 1024, 27)": {
+ "SPLITK": 16
+ },
+ "(2^8, 1024, 4096, 27)": {
+ "SPLITK": 4
+ },
+ "(2^10, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 512, 128, 27)": {
+ "SPLITK": 32
+ },
+ "(2^10, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 512, 128, 27)": {
+ "SPLITK": 4
+ },
+ "(2^14, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^7, 1024, 1024, 27)": {
+ "SPLITK": 4
+ },
+ "(2^7, 1024, 4096, 27)": {
+ "SPLITK": 16
+ },
+ "(2^14, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^12, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^10, 256, 256, 27)": {
+ "SPLITK": 16
+ },
+ "(2^12, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^14, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^16, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^23, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^23, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 128, 32, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 256, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 512, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 1024, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 1024, 4096, 27)": {
+ "SPLITK": 1
+ },
+ "(2^17, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^19, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^21, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^11, 256, 64, 27)": {
+ "SPLITK": 32
+ },
+ "(2^14, 64, 64, 27)": {
+ "SPLITK": 2
+ },
+ "(2^14, 64, 16, 27)": {
+ "SPLITK": 4
+ },
+ "(2^12, 128, 128, 27)": {
+ "SPLITK": 4
+ },
+ "(2^12, 128, 32, 27)": {
+ "SPLITK": 32
+ },
+ "(2^10, 256, 64, 27)": {
+ "SPLITK": 128
+ },
+ "(2^8, 512, 512, 27)": {
+ "SPLITK": 64
+ },
+ "(2^8, 512, 128, 27)": {
+ "SPLITK": 256
+ },
+ "(2^15, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^15, 64, 16, 27)": {
+ "SPLITK": 4
+ },
+ "(2^13, 128, 128, 27)": {
+ "SPLITK": 2
+ },
+ "(2^13, 128, 32, 27)": {
+ "SPLITK": 32
+ },
+ "(2^9, 512, 512, 27)": {
+ "SPLITK": 8
+ },
+ "(2^9, 512, 128, 27)": {
+ "SPLITK": 256
+ },
+ "(2^13, 64, 64, 27)": {
+ "SPLITK": 1
+ },
+ "(2^13, 64, 16, 27)": {
+ "SPLITK": 1
+ },
+ "(2^9, 256, 256, 27)": {
+ "SPLITK": 8
+ },
+ "(2^9, 256, 64, 27)": {
+ "SPLITK": 32
+ },
+ "(2^6, 1024, 1024, 27)": {
+ "SPLITK": 8
+ },
+ "(2^18, 512, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^18, 512, 2048, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 256, 256, 27)": {
+ "SPLITK": 1
+ },
+ "(2^20, 256, 1024, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 128, 128, 27)": {
+ "SPLITK": 1
+ },
+ "(2^22, 128, 512, 27)": {
+ "SPLITK": 1
+ },
+ "(2^24, 64, 64, 27)": {
+ "SPLITK": 1
+ }
+ },
+ "flex_gemm.triton.gemm.gemm_nn.gemm_nn_kernel": {},
+ "flex_gemm.triton.gemm.gemm_nn_splitk.gemm_nn_kernel": {},
+ "flex_gemm.triton.gemm.gemm_nn_splitk.gemm_nn_splitk_kernel": {},
+ "flex_gemm.triton.gemm.gemm_nn_splitk.gemm_nn_splitk": {},
+ "flex_gemm.triton.gemm.gemm_nn_splitk_atomic.gemm_nn_splitk_atomic_kernel": {},
+ "flex_gemm.triton.gemm.gemm_nn_splitk_lock.gemm_nn_splitk_lock_kernel": {},
+ "flex_gemm.kernels.triton.grid_sample.indice_weighed_sum_bwd.indice_weighed_sum_bwd_input_kernel": {},
+ "flex_gemm.kernels.triton.grid_sample.indice_weighed_sum_fwd.indice_weighed_sum_fwd_kernel": {
+ "(23, 4194304, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 4194304, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 32,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 1941851, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 7877533, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 2226123, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 12748156, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 1911611, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(22, 5017088, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 4194304, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 1112821, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 33122502, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1284070, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 10949861, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1571524, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 12857151, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 16
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1641261, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 15495770, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1808517, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 9814710, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 32,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1780790, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 14310670, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 32,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 2113485, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 21145957, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 32
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1782768, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 14828658, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 1577958, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(24, 17012742, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 32,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 2345014, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 12887107, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 2168973, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 12754203, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 1873811, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 12506390, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 2223717, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 8,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ },
+ "(23, 14387524, 6, 8, 'torch.float32', 'torch.uint32', 'torch.float32', 'torch.float32')": {
+ "kwargs": {
+ "BM": 16,
+ "BK": 8
+ },
+ "num_warps": 2,
+ "num_ctas": 1,
+ "num_stages": 2,
+ "num_buffers_warp_spec": 0,
+ "num_consumer_groups": 0,
+ "reg_dec_producer": 0,
+ "reg_inc_consumer": 0,
+ "maxnreg": null,
+ "pre_hook": null
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TRELLIS.2/packages.txt b/TRELLIS.2/packages.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/TRELLIS.2/requirements.txt b/TRELLIS.2/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..46849ad5eaccfcfd491df9e8ac7c1d18a069327a
--- /dev/null
+++ b/TRELLIS.2/requirements.txt
@@ -0,0 +1,23 @@
+--extra-index-url https://download.pytorch.org/whl/cu124
+
+torch==2.6.0
+torchvision==0.21.0
+triton==3.2.0
+pillow==12.0.0
+imageio==2.37.2
+imageio-ffmpeg==0.6.0
+tqdm==4.67.1
+easydict==1.13
+opencv-python-headless==4.12.0.88
+trimesh==4.10.1
+transformers==4.57.3
+zstandard==0.25.0
+kornia==0.8.2
+timm==1.0.22
+git+https://github.com/EasternJournalist/utils3d.git@9a4eb15e4021b67b12c460c7057d642626897ec8
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/cumesh-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/flex_gemm-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/o_voxel-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/nvdiffrast-0.4.0-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/nvdiffrec_render-0.0.0-cp310-cp310-linux_x86_64.whl
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/__init__.py b/TRELLIS.2/trellis2/__init__.py
new file mode 100755
index 0000000000000000000000000000000000000000..20d240afc9c26a21aee76954628b3d4ef9a1ccbd
--- /dev/null
+++ b/TRELLIS.2/trellis2/__init__.py
@@ -0,0 +1,6 @@
+from . import models
+from . import modules
+from . import pipelines
+from . import renderers
+from . import representations
+from . import utils
diff --git a/TRELLIS.2/trellis2/modules/attention/__init__.py b/TRELLIS.2/trellis2/modules/attention/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e90e901f9b942e18aaa5022b3ea167784e52d42a
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/attention/__init__.py
@@ -0,0 +1,3 @@
+from .full_attn import *
+from .modules import *
+from .rope import *
diff --git a/TRELLIS.2/trellis2/modules/attention/config.py b/TRELLIS.2/trellis2/modules/attention/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6d5180cfc92d0121aa9edd8b7f07f72c4f7ad9f
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/attention/config.py
@@ -0,0 +1,32 @@
+from typing import *
+
+BACKEND = 'flash_attn'
+DEBUG = False
+
+def __from_env():
+ import os
+
+ global BACKEND
+ global DEBUG
+
+ env_attn_backend = os.environ.get('ATTN_BACKEND')
+ env_attn_debug = os.environ.get('ATTN_DEBUG')
+
+ if env_attn_backend is not None and env_attn_backend in ['xformers', 'flash_attn', 'flash_attn_3', 'sdpa', 'naive']:
+ BACKEND = env_attn_backend
+ if env_attn_debug is not None:
+ DEBUG = env_attn_debug == '1'
+
+ print(f"[ATTENTION] Using backend: {BACKEND}")
+
+
+__from_env()
+
+
+def set_backend(backend: Literal['xformers', 'flash_attn']):
+ global BACKEND
+ BACKEND = backend
+
+def set_debug(debug: bool):
+ global DEBUG
+ DEBUG = debug
diff --git a/TRELLIS.2/trellis2/modules/attention/full_attn.py b/TRELLIS.2/trellis2/modules/attention/full_attn.py
new file mode 100644
index 0000000000000000000000000000000000000000..e2f9b2af8dfb90f43298042f607c16258516df4c
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/attention/full_attn.py
@@ -0,0 +1,145 @@
+from typing import *
+import torch
+import math
+from . import config
+
+
+__all__ = [
+ 'scaled_dot_product_attention',
+]
+
+
+def _naive_sdpa(q, k, v):
+ """
+ Naive implementation of scaled dot product attention.
+ """
+ q = q.permute(0, 2, 1, 3) # [N, H, L, C]
+ k = k.permute(0, 2, 1, 3) # [N, H, L, C]
+ v = v.permute(0, 2, 1, 3) # [N, H, L, C]
+ scale_factor = 1 / math.sqrt(q.size(-1))
+ attn_weight = q @ k.transpose(-2, -1) * scale_factor
+ attn_weight = torch.softmax(attn_weight, dim=-1)
+ out = attn_weight @ v
+ out = out.permute(0, 2, 1, 3) # [N, L, H, C]
+ return out
+
+
+@overload
+def scaled_dot_product_attention(qkv: torch.Tensor) -> torch.Tensor:
+ """
+ Apply scaled dot product attention.
+
+ Args:
+ qkv (torch.Tensor): A [N, L, 3, H, C] tensor containing Qs, Ks, and Vs.
+ """
+ ...
+
+@overload
+def scaled_dot_product_attention(q: torch.Tensor, kv: torch.Tensor) -> torch.Tensor:
+ """
+ Apply scaled dot product attention.
+
+ Args:
+ q (torch.Tensor): A [N, L, H, C] tensor containing Qs.
+ kv (torch.Tensor): A [N, L, 2, H, C] tensor containing Ks and Vs.
+ """
+ ...
+
+@overload
+def scaled_dot_product_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor:
+ """
+ Apply scaled dot product attention.
+
+ Args:
+ q (torch.Tensor): A [N, L, H, Ci] tensor containing Qs.
+ k (torch.Tensor): A [N, L, H, Ci] tensor containing Ks.
+ v (torch.Tensor): A [N, L, H, Co] tensor containing Vs.
+
+ Note:
+ k and v are assumed to have the same coordinate map.
+ """
+ ...
+
+def scaled_dot_product_attention(*args, **kwargs):
+ arg_names_dict = {
+ 1: ['qkv'],
+ 2: ['q', 'kv'],
+ 3: ['q', 'k', 'v']
+ }
+ num_all_args = len(args) + len(kwargs)
+ assert num_all_args in arg_names_dict, f"Invalid number of arguments, got {num_all_args}, expected 1, 2, or 3"
+ for key in arg_names_dict[num_all_args][len(args):]:
+ assert key in kwargs, f"Missing argument {key}"
+
+ if num_all_args == 1:
+ qkv = args[0] if len(args) > 0 else kwargs['qkv']
+ assert len(qkv.shape) == 5 and qkv.shape[2] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, L, 3, H, C]"
+ device = qkv.device
+
+ elif num_all_args == 2:
+ q = args[0] if len(args) > 0 else kwargs['q']
+ kv = args[1] if len(args) > 1 else kwargs['kv']
+ assert q.shape[0] == kv.shape[0], f"Batch size mismatch, got {q.shape[0]} and {kv.shape[0]}"
+ assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, C]"
+ assert len(kv.shape) == 5, f"Invalid shape for kv, got {kv.shape}, expected [N, L, 2, H, C]"
+ device = q.device
+
+ elif num_all_args == 3:
+ q = args[0] if len(args) > 0 else kwargs['q']
+ k = args[1] if len(args) > 1 else kwargs['k']
+ v = args[2] if len(args) > 2 else kwargs['v']
+ assert q.shape[0] == k.shape[0] == v.shape[0], f"Batch size mismatch, got {q.shape[0]}, {k.shape[0]}, and {v.shape[0]}"
+ assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, Ci]"
+ assert len(k.shape) == 4, f"Invalid shape for k, got {k.shape}, expected [N, L, H, Ci]"
+ assert len(v.shape) == 4, f"Invalid shape for v, got {v.shape}, expected [N, L, H, Co]"
+ device = q.device
+
+ if config.BACKEND == 'xformers':
+ if 'xops' not in globals():
+ import xformers.ops as xops
+ if num_all_args == 1:
+ q, k, v = qkv.unbind(dim=2)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=2)
+ out = xops.memory_efficient_attention(q, k, v)
+ elif config.BACKEND == 'flash_attn':
+ if 'flash_attn' not in globals():
+ import flash_attn
+ if num_all_args == 1:
+ out = flash_attn.flash_attn_qkvpacked_func(qkv)
+ elif num_all_args == 2:
+ out = flash_attn.flash_attn_kvpacked_func(q, kv)
+ elif num_all_args == 3:
+ out = flash_attn.flash_attn_func(q, k, v)
+ elif config.BACKEND == 'flash_attn_3':
+ if 'flash_attn_3' not in globals():
+ import flash_attn_interface as flash_attn_3
+ if num_all_args == 1:
+ out = flash_attn_3.flash_attn_qkvpacked_func(qkv)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=2)
+ out = flash_attn_3.flash_attn_func(q, k, v)
+ elif num_all_args == 3:
+ out = flash_attn_3.flash_attn_func(q, k, v)
+ elif config.BACKEND == 'sdpa':
+ if 'sdpa' not in globals():
+ from torch.nn.functional import scaled_dot_product_attention as sdpa
+ if num_all_args == 1:
+ q, k, v = qkv.unbind(dim=2)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=2)
+ q = q.permute(0, 2, 1, 3) # [N, H, L, C]
+ k = k.permute(0, 2, 1, 3) # [N, H, L, C]
+ v = v.permute(0, 2, 1, 3) # [N, H, L, C]
+ out = sdpa(q, k, v) # [N, H, L, C]
+ out = out.permute(0, 2, 1, 3) # [N, L, H, C]
+ elif config.BACKEND == 'naive':
+ if num_all_args == 1:
+ q, k, v = qkv.unbind(dim=2)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=2)
+ out = _naive_sdpa(q, k, v)
+ else:
+ raise ValueError(f"Unknown attention module: {config.BACKEND}")
+
+ return out
diff --git a/TRELLIS.2/trellis2/modules/attention/modules.py b/TRELLIS.2/trellis2/modules/attention/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..492784c7ba8f572c4820b604f51c924ed564ab00
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/attention/modules.py
@@ -0,0 +1,102 @@
+from typing import *
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .full_attn import scaled_dot_product_attention
+from .rope import RotaryPositionEmbedder
+
+
+class MultiHeadRMSNorm(nn.Module):
+ def __init__(self, dim: int, heads: int):
+ super().__init__()
+ self.scale = dim ** 0.5
+ self.gamma = nn.Parameter(torch.ones(heads, dim))
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return (F.normalize(x.float(), dim = -1) * self.gamma * self.scale).to(x.dtype)
+
+
+class MultiHeadAttention(nn.Module):
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ ctx_channels: Optional[int]=None,
+ type: Literal["self", "cross"] = "self",
+ attn_mode: Literal["full", "windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ qkv_bias: bool = True,
+ use_rope: bool = False,
+ rope_freq: Tuple[float, float] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ ):
+ super().__init__()
+ assert channels % num_heads == 0
+ assert type in ["self", "cross"], f"Invalid attention type: {type}"
+ assert attn_mode in ["full", "windowed"], f"Invalid attention mode: {attn_mode}"
+ assert type == "self" or attn_mode == "full", "Cross-attention only supports full attention"
+
+ if attn_mode == "windowed":
+ raise NotImplementedError("Windowed attention is not yet implemented")
+
+ self.channels = channels
+ self.head_dim = channels // num_heads
+ self.ctx_channels = ctx_channels if ctx_channels is not None else channels
+ self.num_heads = num_heads
+ self._type = type
+ self.attn_mode = attn_mode
+ self.window_size = window_size
+ self.shift_window = shift_window
+ self.use_rope = use_rope
+ self.qk_rms_norm = qk_rms_norm
+
+ if self._type == "self":
+ self.to_qkv = nn.Linear(channels, channels * 3, bias=qkv_bias)
+ else:
+ self.to_q = nn.Linear(channels, channels, bias=qkv_bias)
+ self.to_kv = nn.Linear(self.ctx_channels, channels * 2, bias=qkv_bias)
+
+ if self.qk_rms_norm:
+ self.q_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads)
+ self.k_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads)
+
+ self.to_out = nn.Linear(channels, channels)
+
+ def forward(self, x: torch.Tensor, context: Optional[torch.Tensor] = None, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ B, L, C = x.shape
+ if self._type == "self":
+ qkv = self.to_qkv(x)
+ qkv = qkv.reshape(B, L, 3, self.num_heads, -1)
+
+ if self.attn_mode == "full":
+ if self.qk_rms_norm or self.use_rope:
+ q, k, v = qkv.unbind(dim=2)
+ if self.qk_rms_norm:
+ q = self.q_rms_norm(q)
+ k = self.k_rms_norm(k)
+ if self.use_rope:
+ assert phases is not None, "Phases must be provided for RoPE"
+ q = RotaryPositionEmbedder.apply_rotary_embedding(q, phases)
+ k = RotaryPositionEmbedder.apply_rotary_embedding(k, phases)
+ h = scaled_dot_product_attention(q, k, v)
+ else:
+ h = scaled_dot_product_attention(qkv)
+ elif self.attn_mode == "windowed":
+ raise NotImplementedError("Windowed attention is not yet implemented")
+ else:
+ Lkv = context.shape[1]
+ q = self.to_q(x)
+ kv = self.to_kv(context)
+ q = q.reshape(B, L, self.num_heads, -1)
+ kv = kv.reshape(B, Lkv, 2, self.num_heads, -1)
+ if self.qk_rms_norm:
+ q = self.q_rms_norm(q)
+ k, v = kv.unbind(dim=2)
+ k = self.k_rms_norm(k)
+ h = scaled_dot_product_attention(q, k, v)
+ else:
+ h = scaled_dot_product_attention(q, kv)
+ h = h.reshape(B, L, -1)
+ h = self.to_out(h)
+ return h
diff --git a/TRELLIS.2/trellis2/modules/attention/rope.py b/TRELLIS.2/trellis2/modules/attention/rope.py
new file mode 100644
index 0000000000000000000000000000000000000000..1cf6c5b321c2417443ffad3804df97ff5fbe6658
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/attention/rope.py
@@ -0,0 +1,48 @@
+from typing import *
+import torch
+import torch.nn as nn
+
+
+class RotaryPositionEmbedder(nn.Module):
+ def __init__(
+ self,
+ head_dim: int,
+ dim: int = 3,
+ rope_freq: Tuple[float, float] = (1.0, 10000.0)
+ ):
+ super().__init__()
+ assert head_dim % 2 == 0, "Head dim must be divisible by 2"
+ self.head_dim = head_dim
+ self.dim = dim
+ self.rope_freq = rope_freq
+ self.freq_dim = head_dim // 2 // dim
+ self.freqs = torch.arange(self.freq_dim, dtype=torch.float32) / self.freq_dim
+ self.freqs = rope_freq[0] / (rope_freq[1] ** (self.freqs))
+
+ def _get_phases(self, indices: torch.Tensor) -> torch.Tensor:
+ self.freqs = self.freqs.to(indices.device)
+ phases = torch.outer(indices, self.freqs)
+ phases = torch.polar(torch.ones_like(phases), phases)
+ return phases
+
+ @staticmethod
+ def apply_rotary_embedding(x: torch.Tensor, phases: torch.Tensor) -> torch.Tensor:
+ x_complex = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
+ x_rotated = x_complex * phases.unsqueeze(-2)
+ x_embed = torch.view_as_real(x_rotated).reshape(*x_rotated.shape[:-1], -1).to(x.dtype)
+ return x_embed
+
+ def forward(self, indices: torch.Tensor) -> torch.Tensor:
+ """
+ Args:
+ indices (torch.Tensor): [..., N, C] tensor of spatial positions
+ """
+ assert indices.shape[-1] == self.dim, f"Last dim of indices must be {self.dim}"
+ phases = self._get_phases(indices.reshape(-1)).reshape(*indices.shape[:-1], -1)
+ if phases.shape[-1] < self.head_dim // 2:
+ padn = self.head_dim // 2 - phases.shape[-1]
+ phases = torch.cat([phases, torch.polar(
+ torch.ones(*phases.shape[:-1], padn, device=phases.device),
+ torch.zeros(*phases.shape[:-1], padn, device=phases.device)
+ )], dim=-1)
+ return phases
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/image_feature_extractor.py b/TRELLIS.2/trellis2/modules/image_feature_extractor.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3cb515ad1152752b09fef9999cc5ff44bd885f7
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/image_feature_extractor.py
@@ -0,0 +1,118 @@
+from typing import *
+import torch
+import torch.nn.functional as F
+from torchvision import transforms
+from transformers import DINOv3ViTModel
+import numpy as np
+from PIL import Image
+
+
+class DinoV2FeatureExtractor:
+ """
+ Feature extractor for DINOv2 models.
+ """
+ def __init__(self, model_name: str):
+ self.model_name = model_name
+ self.model = torch.hub.load('facebookresearch/dinov2', model_name, pretrained=True)
+ self.model.eval()
+ self.transform = transforms.Compose([
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
+ ])
+
+ def to(self, device):
+ self.model.to(device)
+
+ def cuda(self):
+ self.model.cuda()
+
+ def cpu(self):
+ self.model.cpu()
+
+ @torch.no_grad()
+ def __call__(self, image: Union[torch.Tensor, List[Image.Image]]) -> torch.Tensor:
+ """
+ Extract features from the image.
+
+ Args:
+ image: A batch of images as a tensor of shape (B, C, H, W) or a list of PIL images.
+
+ Returns:
+ A tensor of shape (B, N, D) where N is the number of patches and D is the feature dimension.
+ """
+ if isinstance(image, torch.Tensor):
+ assert image.ndim == 4, "Image tensor should be batched (B, C, H, W)"
+ elif isinstance(image, list):
+ assert all(isinstance(i, Image.Image) for i in image), "Image list should be list of PIL images"
+ image = [i.resize((518, 518), Image.LANCZOS) for i in image]
+ image = [np.array(i.convert('RGB')).astype(np.float32) / 255 for i in image]
+ image = [torch.from_numpy(i).permute(2, 0, 1).float() for i in image]
+ image = torch.stack(image).cuda()
+ else:
+ raise ValueError(f"Unsupported type of image: {type(image)}")
+
+ image = self.transform(image).cuda()
+ features = self.model(image, is_training=True)['x_prenorm']
+ patchtokens = F.layer_norm(features, features.shape[-1:])
+ return patchtokens
+
+
+class DinoV3FeatureExtractor:
+ """
+ Feature extractor for DINOv3 models.
+ """
+ def __init__(self, model_name: str, image_size=512):
+ self.model_name = model_name
+ self.model = DINOv3ViTModel.from_pretrained(model_name)
+ self.model.eval()
+ self.image_size = image_size
+ self.transform = transforms.Compose([
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
+ ])
+
+ def to(self, device):
+ self.model.to(device)
+
+ def cuda(self):
+ self.model.cuda()
+
+ def cpu(self):
+ self.model.cpu()
+
+ def extract_features(self, image: torch.Tensor) -> torch.Tensor:
+ image = image.to(self.model.embeddings.patch_embeddings.weight.dtype)
+ hidden_states = self.model.embeddings(image, bool_masked_pos=None)
+ position_embeddings = self.model.rope_embeddings(image)
+
+ for i, layer_module in enumerate(self.model.layer):
+ hidden_states = layer_module(
+ hidden_states,
+ position_embeddings=position_embeddings,
+ )
+
+ return F.layer_norm(hidden_states, hidden_states.shape[-1:])
+
+ @torch.no_grad()
+ def __call__(self, image: Union[torch.Tensor, List[Image.Image]]) -> torch.Tensor:
+ """
+ Extract features from the image.
+
+ Args:
+ image: A batch of images as a tensor of shape (B, C, H, W) or a list of PIL images.
+
+ Returns:
+ A tensor of shape (B, N, D) where N is the number of patches and D is the feature dimension.
+ """
+ if isinstance(image, torch.Tensor):
+ assert image.ndim == 4, "Image tensor should be batched (B, C, H, W)"
+ elif isinstance(image, list):
+ assert all(isinstance(i, Image.Image) for i in image), "Image list should be list of PIL images"
+ image = [i.resize((self.image_size, self.image_size), Image.LANCZOS) for i in image]
+ image = [np.array(i.convert('RGB')).astype(np.float32) / 255 for i in image]
+ image = [torch.from_numpy(i).permute(2, 0, 1).float() for i in image]
+ image = torch.stack(image).cuda()
+ else:
+ raise ValueError(f"Unsupported type of image: {type(image)}")
+
+ image = self.transform(image).cuda()
+ features = self.extract_features(image)
+ return features
diff --git a/TRELLIS.2/trellis2/modules/norm.py b/TRELLIS.2/trellis2/modules/norm.py
new file mode 100644
index 0000000000000000000000000000000000000000..78675d0f850d2e34d3c90b5d6bc14db708e5b400
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/norm.py
@@ -0,0 +1,32 @@
+import torch
+import torch.nn as nn
+from .utils import manual_cast
+
+
+class LayerNorm32(nn.LayerNorm):
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ x_dtype = x.dtype
+ x = manual_cast(x, torch.float32)
+ o = super().forward(x)
+ return manual_cast(o, x_dtype)
+
+
+class GroupNorm32(nn.GroupNorm):
+ """
+ A GroupNorm layer that converts to float32 before the forward pass.
+ """
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ x_dtype = x.dtype
+ x = manual_cast(x, torch.float32)
+ o = super().forward(x)
+ return manual_cast(o, x_dtype)
+
+
+class ChannelLayerNorm32(LayerNorm32):
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ DIM = x.dim()
+ x = x.permute(0, *range(2, DIM), 1).contiguous()
+ x = super().forward(x)
+ x = x.permute(0, DIM-1, *range(1, DIM-1)).contiguous()
+ return x
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/sparse/__init__.py b/TRELLIS.2/trellis2/modules/sparse/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e73f232abc6f31cafeac4172a96150906ba20b7b
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/__init__.py
@@ -0,0 +1,69 @@
+from . import config
+import importlib
+
+__attributes = {
+ 'VarLenTensor': 'basic',
+ 'varlen_cat': 'basic',
+ 'varlen_unbind': 'basic',
+ 'SparseTensor': 'basic',
+ 'sparse_cat': 'basic',
+ 'sparse_unbind': 'basic',
+ 'SparseGroupNorm': 'norm',
+ 'SparseLayerNorm': 'norm',
+ 'SparseGroupNorm32': 'norm',
+ 'SparseLayerNorm32': 'norm',
+ 'SparseReLU': 'nonlinearity',
+ 'SparseSiLU': 'nonlinearity',
+ 'SparseGELU': 'nonlinearity',
+ 'SparseActivation': 'nonlinearity',
+ 'SparseLinear': 'linear',
+ 'sparse_scaled_dot_product_attention': 'attention',
+ 'SerializeMode': 'attention',
+ 'sparse_serialized_scaled_dot_product_self_attention': 'attention',
+ 'sparse_windowed_scaled_dot_product_self_attention': 'attention',
+ 'sparse_windowed_scaled_dot_product_cross_attention': 'attention',
+ 'SparseRotaryPositionEmbedder': 'attention',
+ 'SparseMultiHeadAttention': 'attention',
+ 'SparseConv3d': 'conv',
+ 'SparseInverseConv3d': 'conv',
+ 'SparseDownsample': 'spatial',
+ 'SparseUpsample': 'spatial',
+ 'SparseSubdivide': 'spatial',
+ 'SparseSpatial2Channel': 'spatial',
+ 'SparseChannel2Spatial': 'spatial',
+ 'sparse_nearest_interpolate': 'spatial',
+ 'sparse_trilinear_interpolate': 'spatial',
+ 'encode_seq': 'serialize',
+ 'decode_seq': 'serialize',
+}
+
+__submodules = ['transformer', 'conv']
+
+__all__ = list(__attributes.keys()) + __submodules
+
+def __getattr__(name):
+ if name not in globals():
+ if name in __attributes:
+ module_name = __attributes[name]
+ module = importlib.import_module(f".{module_name}", __name__)
+ globals()[name] = getattr(module, name)
+ elif name in __submodules:
+ module = importlib.import_module(f".{name}", __name__)
+ globals()[name] = module
+ else:
+ raise AttributeError(f"module {__name__} has no attribute {name}")
+ return globals()[name]
+
+
+# For Pylance
+if __name__ == '__main__':
+ from .basic import *
+ from .norm import *
+ from .nonlinearity import *
+ from .linear import *
+ from .attention import *
+ from .conv import *
+ from .spatial import *
+ from .serialize import *
+ import transformer
+ import conv
diff --git a/TRELLIS.2/trellis2/modules/sparse/attention/__init__.py b/TRELLIS.2/trellis2/modules/sparse/attention/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..18ab3cc0a2c96b430009c3b709db3eb28ce7ccc0
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/attention/__init__.py
@@ -0,0 +1,3 @@
+from .full_attn import *
+from .windowed_attn import *
+from .modules import *
diff --git a/TRELLIS.2/trellis2/modules/sparse/attention/full_attn.py b/TRELLIS.2/trellis2/modules/sparse/attention/full_attn.py
new file mode 100644
index 0000000000000000000000000000000000000000..4eb74d24c37c1951b579ecce5fabe97c4f0d02bf
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/attention/full_attn.py
@@ -0,0 +1,220 @@
+from typing import *
+import torch
+from .. import VarLenTensor
+from .. import config
+
+
+__all__ = [
+ 'sparse_scaled_dot_product_attention',
+]
+
+
+@overload
+def sparse_scaled_dot_product_attention(qkv: VarLenTensor) -> VarLenTensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ qkv (VarLenTensor): A [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs.
+ """
+ ...
+
+@overload
+def sparse_scaled_dot_product_attention(q: VarLenTensor, kv: Union[VarLenTensor, torch.Tensor]) -> VarLenTensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ q (VarLenTensor): A [N, *, H, C] sparse tensor containing Qs.
+ kv (VarLenTensor or torch.Tensor): A [N, *, 2, H, C] sparse tensor or a [N, L, 2, H, C] dense tensor containing Ks and Vs.
+ """
+ ...
+
+@overload
+def sparse_scaled_dot_product_attention(q: torch.Tensor, kv: VarLenTensor) -> torch.Tensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ q (torch.Tensor): A [N, L, H, C] dense tensor containing Qs.
+ kv (VarLenTensor): A [N, *, 2, H, C] sparse tensor containing Ks and Vs.
+ """
+ ...
+
+@overload
+def sparse_scaled_dot_product_attention(q: VarLenTensor, k: VarLenTensor, v: VarLenTensor) -> VarLenTensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ q (VarLenTensor): A [N, *, H, Ci] sparse tensor containing Qs.
+ k (VarLenTensor): A [N, *, H, Ci] sparse tensor containing Ks.
+ v (VarLenTensor): A [N, *, H, Co] sparse tensor containing Vs.
+
+ Note:
+ k and v are assumed to have the same coordinate map.
+ """
+ ...
+
+@overload
+def sparse_scaled_dot_product_attention(q: VarLenTensor, k: torch.Tensor, v: torch.Tensor) -> VarLenTensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ q (VarLenTensor): A [N, *, H, Ci] sparse tensor containing Qs.
+ k (torch.Tensor): A [N, L, H, Ci] dense tensor containing Ks.
+ v (torch.Tensor): A [N, L, H, Co] dense tensor containing Vs.
+ """
+ ...
+
+@overload
+def sparse_scaled_dot_product_attention(q: torch.Tensor, k: VarLenTensor, v: VarLenTensor) -> torch.Tensor:
+ """
+ Apply scaled dot product attention to a sparse tensor.
+
+ Args:
+ q (torch.Tensor): A [N, L, H, Ci] dense tensor containing Qs.
+ k (VarLenTensor): A [N, *, H, Ci] sparse tensor containing Ks.
+ v (VarLenTensor): A [N, *, H, Co] sparse tensor containing Vs.
+ """
+ ...
+
+def sparse_scaled_dot_product_attention(*args, **kwargs):
+ arg_names_dict = {
+ 1: ['qkv'],
+ 2: ['q', 'kv'],
+ 3: ['q', 'k', 'v']
+ }
+ num_all_args = len(args) + len(kwargs)
+ assert num_all_args in arg_names_dict, f"Invalid number of arguments, got {num_all_args}, expected 1, 2, or 3"
+ for key in arg_names_dict[num_all_args][len(args):]:
+ assert key in kwargs, f"Missing argument {key}"
+
+ if num_all_args == 1:
+ qkv = args[0] if len(args) > 0 else kwargs['qkv']
+ assert isinstance(qkv, VarLenTensor), f"qkv must be a VarLenTensor, got {type(qkv)}"
+ assert len(qkv.shape) == 4 and qkv.shape[1] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, *, 3, H, C]"
+ device = qkv.device
+
+ s = qkv
+ q_seqlen = [qkv.layout[i].stop - qkv.layout[i].start for i in range(qkv.shape[0])]
+ kv_seqlen = q_seqlen
+ qkv = qkv.feats # [T, 3, H, C]
+
+ elif num_all_args == 2:
+ q = args[0] if len(args) > 0 else kwargs['q']
+ kv = args[1] if len(args) > 1 else kwargs['kv']
+ assert isinstance(q, VarLenTensor) and isinstance(kv, (VarLenTensor, torch.Tensor)) or \
+ isinstance(q, torch.Tensor) and isinstance(kv, VarLenTensor), \
+ f"Invalid types, got {type(q)} and {type(kv)}"
+ assert q.shape[0] == kv.shape[0], f"Batch size mismatch, got {q.shape[0]} and {kv.shape[0]}"
+ device = q.device
+
+ if isinstance(q, VarLenTensor):
+ assert len(q.shape) == 3, f"Invalid shape for q, got {q.shape}, expected [N, *, H, C]"
+ s = q
+ q_seqlen = [q.layout[i].stop - q.layout[i].start for i in range(q.shape[0])]
+ q = q.feats # [T_Q, H, C]
+ else:
+ assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, C]"
+ s = None
+ N, L, H, C = q.shape
+ q_seqlen = [L] * N
+ q = q.reshape(N * L, H, C) # [T_Q, H, C]
+
+ if isinstance(kv, VarLenTensor):
+ assert len(kv.shape) == 4 and kv.shape[1] == 2, f"Invalid shape for kv, got {kv.shape}, expected [N, *, 2, H, C]"
+ kv_seqlen = [kv.layout[i].stop - kv.layout[i].start for i in range(kv.shape[0])]
+ kv = kv.feats # [T_KV, 2, H, C]
+ else:
+ assert len(kv.shape) == 5, f"Invalid shape for kv, got {kv.shape}, expected [N, L, 2, H, C]"
+ N, L, _, H, C = kv.shape
+ kv_seqlen = [L] * N
+ kv = kv.reshape(N * L, 2, H, C) # [T_KV, 2, H, C]
+
+ elif num_all_args == 3:
+ q = args[0] if len(args) > 0 else kwargs['q']
+ k = args[1] if len(args) > 1 else kwargs['k']
+ v = args[2] if len(args) > 2 else kwargs['v']
+ assert isinstance(q, VarLenTensor) and isinstance(k, (VarLenTensor, torch.Tensor)) and type(k) == type(v) or \
+ isinstance(q, torch.Tensor) and isinstance(k, VarLenTensor) and isinstance(v, VarLenTensor), \
+ f"Invalid types, got {type(q)}, {type(k)}, and {type(v)}"
+ assert q.shape[0] == k.shape[0] == v.shape[0], f"Batch size mismatch, got {q.shape[0]}, {k.shape[0]}, and {v.shape[0]}"
+ device = q.device
+
+ if isinstance(q, VarLenTensor):
+ assert len(q.shape) == 3, f"Invalid shape for q, got {q.shape}, expected [N, *, H, Ci]"
+ s = q
+ q_seqlen = [q.layout[i].stop - q.layout[i].start for i in range(q.shape[0])]
+ q = q.feats # [T_Q, H, Ci]
+ else:
+ assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, Ci]"
+ s = None
+ N, L, H, CI = q.shape
+ q_seqlen = [L] * N
+ q = q.reshape(N * L, H, CI) # [T_Q, H, Ci]
+
+ if isinstance(k, VarLenTensor):
+ assert len(k.shape) == 3, f"Invalid shape for k, got {k.shape}, expected [N, *, H, Ci]"
+ assert len(v.shape) == 3, f"Invalid shape for v, got {v.shape}, expected [N, *, H, Co]"
+ kv_seqlen = [k.layout[i].stop - k.layout[i].start for i in range(k.shape[0])]
+ k = k.feats # [T_KV, H, Ci]
+ v = v.feats # [T_KV, H, Co]
+ else:
+ assert len(k.shape) == 4, f"Invalid shape for k, got {k.shape}, expected [N, L, H, Ci]"
+ assert len(v.shape) == 4, f"Invalid shape for v, got {v.shape}, expected [N, L, H, Co]"
+ N, L, H, CI, CO = *k.shape, v.shape[-1]
+ kv_seqlen = [L] * N
+ k = k.reshape(N * L, H, CI) # [T_KV, H, Ci]
+ v = v.reshape(N * L, H, CO) # [T_KV, H, Co]
+
+ if config.ATTN == 'xformers':
+ if 'xops' not in globals():
+ import xformers.ops as xops
+ if num_all_args == 1:
+ q, k, v = qkv.unbind(dim=1)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=1)
+ q = q.unsqueeze(0)
+ k = k.unsqueeze(0)
+ v = v.unsqueeze(0)
+ mask = xops.fmha.BlockDiagonalMask.from_seqlens(q_seqlen, kv_seqlen)
+ out = xops.memory_efficient_attention(q, k, v, mask)[0]
+ elif config.ATTN == 'flash_attn':
+ if 'flash_attn' not in globals():
+ import flash_attn
+ cu_seqlens_q = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(q_seqlen), dim=0)]).int().to(device)
+ if num_all_args in [2, 3]:
+ cu_seqlens_kv = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(kv_seqlen), dim=0)]).int().to(device)
+ if num_all_args == 1:
+ out = flash_attn.flash_attn_varlen_qkvpacked_func(qkv, cu_seqlens_q, max(q_seqlen))
+ elif num_all_args == 2:
+ out = flash_attn.flash_attn_varlen_kvpacked_func(q, kv, cu_seqlens_q, cu_seqlens_kv, max(q_seqlen), max(kv_seqlen))
+ elif num_all_args == 3:
+ out = flash_attn.flash_attn_varlen_func(q, k, v, cu_seqlens_q, cu_seqlens_kv, max(q_seqlen), max(kv_seqlen))
+ elif config.ATTN == 'flash_attn_3':
+ if 'flash_attn_3' not in globals():
+ import flash_attn_interface as flash_attn_3
+ cu_seqlens_q = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(q_seqlen), dim=0)]).int().to(device)
+ if num_all_args == 1:
+ q, k, v = qkv.unbind(dim=1)
+ cu_seqlens_kv = cu_seqlens_q.clone()
+ max_q_seqlen = max_kv_seqlen = max(q_seqlen)
+ elif num_all_args == 2:
+ k, v = kv.unbind(dim=1)
+ cu_seqlens_kv = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(kv_seqlen), dim=0)]).int().to(device)
+ max_q_seqlen = max(q_seqlen)
+ max_kv_seqlen = max(kv_seqlen)
+ elif num_all_args == 3:
+ cu_seqlens_kv = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(kv_seqlen), dim=0)]).int().to(device)
+ max_q_seqlen = max(q_seqlen)
+ max_kv_seqlen = max(kv_seqlen)
+ out = flash_attn_3.flash_attn_varlen_func(q, k, v, cu_seqlens_q, cu_seqlens_kv, max_q_seqlen, max_kv_seqlen)
+ else:
+ raise ValueError(f"Unknown attention module: {config.ATTN}")
+
+ if s is not None:
+ return s.replace(out)
+ else:
+ return out.reshape(N, L, H, -1)
diff --git a/TRELLIS.2/trellis2/modules/sparse/attention/modules.py b/TRELLIS.2/trellis2/modules/sparse/attention/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..d762b4b2e01335d26d856b3fe82eca31a2735123
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/attention/modules.py
@@ -0,0 +1,141 @@
+from typing import *
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from .. import VarLenTensor, SparseTensor
+from .full_attn import sparse_scaled_dot_product_attention
+from .windowed_attn import sparse_windowed_scaled_dot_product_self_attention
+from .rope import SparseRotaryPositionEmbedder
+
+
+class SparseMultiHeadRMSNorm(nn.Module):
+ def __init__(self, dim: int, heads: int):
+ super().__init__()
+ self.scale = dim ** 0.5
+ self.gamma = nn.Parameter(torch.ones(heads, dim))
+
+ def forward(self, x: Union[VarLenTensor, torch.Tensor]) -> Union[VarLenTensor, torch.Tensor]:
+ x_type = x.dtype
+ x = x.float()
+ if isinstance(x, VarLenTensor):
+ x = x.replace(F.normalize(x.feats, dim=-1) * self.gamma * self.scale)
+ else:
+ x = F.normalize(x, dim=-1) * self.gamma * self.scale
+ return x.to(x_type)
+
+
+class SparseMultiHeadAttention(nn.Module):
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ ctx_channels: Optional[int] = None,
+ type: Literal["self", "cross"] = "self",
+ attn_mode: Literal["full", "windowed", "double_windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ qkv_bias: bool = True,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ ):
+ super().__init__()
+ assert channels % num_heads == 0
+ assert type in ["self", "cross"], f"Invalid attention type: {type}"
+ assert attn_mode in ["full", "windowed", "double_windowed"], f"Invalid attention mode: {attn_mode}"
+ assert type == "self" or attn_mode == "full", "Cross-attention only supports full attention"
+ assert type == "self" or use_rope is False, "Rotary position embeddings only supported for self-attention"
+ if attn_mode == 'double_windowed':
+ assert window_size % 2 == 0, "Window size must be even for double windowed attention"
+ assert num_heads % 2 == 0, "Number of heads must be even for double windowed attention"
+ self.channels = channels
+ self.head_dim = channels // num_heads
+ self.ctx_channels = ctx_channels if ctx_channels is not None else channels
+ self.num_heads = num_heads
+ self._type = type
+ self.attn_mode = attn_mode
+ self.window_size = window_size
+ self.shift_window = shift_window
+ self.use_rope = use_rope
+ self.qk_rms_norm = qk_rms_norm
+
+ if self._type == "self":
+ self.to_qkv = nn.Linear(channels, channels * 3, bias=qkv_bias)
+ else:
+ self.to_q = nn.Linear(channels, channels, bias=qkv_bias)
+ self.to_kv = nn.Linear(self.ctx_channels, channels * 2, bias=qkv_bias)
+
+ if self.qk_rms_norm:
+ self.q_rms_norm = SparseMultiHeadRMSNorm(self.head_dim, num_heads)
+ self.k_rms_norm = SparseMultiHeadRMSNorm(self.head_dim, num_heads)
+
+ self.to_out = nn.Linear(channels, channels)
+
+ if use_rope:
+ self.rope = SparseRotaryPositionEmbedder(self.head_dim, rope_freq=rope_freq)
+
+ @staticmethod
+ def _linear(module: nn.Linear, x: Union[VarLenTensor, torch.Tensor]) -> Union[VarLenTensor, torch.Tensor]:
+ if isinstance(x, VarLenTensor):
+ return x.replace(module(x.feats))
+ else:
+ return module(x)
+
+ @staticmethod
+ def _reshape_chs(x: Union[VarLenTensor, torch.Tensor], shape: Tuple[int, ...]) -> Union[VarLenTensor, torch.Tensor]:
+ if isinstance(x, VarLenTensor):
+ return x.reshape(*shape)
+ else:
+ return x.reshape(*x.shape[:2], *shape)
+
+ def _fused_pre(self, x: Union[VarLenTensor, torch.Tensor], num_fused: int) -> Union[VarLenTensor, torch.Tensor]:
+ if isinstance(x, VarLenTensor):
+ x_feats = x.feats.unsqueeze(0)
+ else:
+ x_feats = x
+ x_feats = x_feats.reshape(*x_feats.shape[:2], num_fused, self.num_heads, -1)
+ return x.replace(x_feats.squeeze(0)) if isinstance(x, VarLenTensor) else x_feats
+
+ def forward(self, x: SparseTensor, context: Optional[Union[VarLenTensor, torch.Tensor]] = None) -> SparseTensor:
+ if self._type == "self":
+ qkv = self._linear(self.to_qkv, x)
+ qkv = self._fused_pre(qkv, num_fused=3)
+ if self.qk_rms_norm or self.use_rope:
+ q, k, v = qkv.unbind(dim=-3)
+ if self.qk_rms_norm:
+ q = self.q_rms_norm(q)
+ k = self.k_rms_norm(k)
+ if self.use_rope:
+ q, k = self.rope(q, k)
+ qkv = qkv.replace(torch.stack([q.feats, k.feats, v.feats], dim=1))
+ if self.attn_mode == "full":
+ h = sparse_scaled_dot_product_attention(qkv)
+ elif self.attn_mode == "windowed":
+ h = sparse_windowed_scaled_dot_product_self_attention(
+ qkv, self.window_size, shift_window=self.shift_window
+ )
+ elif self.attn_mode == "double_windowed":
+ qkv0 = qkv.replace(qkv.feats[:, :, self.num_heads//2:])
+ qkv1 = qkv.replace(qkv.feats[:, :, :self.num_heads//2])
+ h0 = sparse_windowed_scaled_dot_product_self_attention(
+ qkv0, self.window_size, shift_window=(0, 0, 0)
+ )
+ h1 = sparse_windowed_scaled_dot_product_self_attention(
+ qkv1, self.window_size, shift_window=tuple([self.window_size//2] * 3)
+ )
+ h = qkv.replace(torch.cat([h0.feats, h1.feats], dim=1))
+ else:
+ q = self._linear(self.to_q, x)
+ q = self._reshape_chs(q, (self.num_heads, -1))
+ kv = self._linear(self.to_kv, context)
+ kv = self._fused_pre(kv, num_fused=2)
+ if self.qk_rms_norm:
+ q = self.q_rms_norm(q)
+ k, v = kv.unbind(dim=-3)
+ k = self.k_rms_norm(k)
+ h = sparse_scaled_dot_product_attention(q, k, v)
+ else:
+ h = sparse_scaled_dot_product_attention(q, kv)
+ h = self._reshape_chs(h, (-1,))
+ h = self._linear(self.to_out, h)
+ return h
diff --git a/TRELLIS.2/trellis2/modules/sparse/attention/rope.py b/TRELLIS.2/trellis2/modules/sparse/attention/rope.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb877291f3430f2cff4329a67b3592e0e3c3f137
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/attention/rope.py
@@ -0,0 +1,58 @@
+from typing import *
+import torch
+import torch.nn as nn
+from ..basic import SparseTensor
+
+
+class SparseRotaryPositionEmbedder(nn.Module):
+ def __init__(
+ self,
+ head_dim: int,
+ dim: int = 3,
+ rope_freq: Tuple[float, float] = (1.0, 10000.0)
+ ):
+ super().__init__()
+ assert head_dim % 2 == 0, "Head dim must be divisible by 2"
+ self.head_dim = head_dim
+ self.dim = dim
+ self.rope_freq = rope_freq
+ self.freq_dim = head_dim // 2 // dim
+ self.freqs = torch.arange(self.freq_dim, dtype=torch.float32) / self.freq_dim
+ self.freqs = rope_freq[0] / (rope_freq[1] ** (self.freqs))
+
+ def _get_phases(self, indices: torch.Tensor) -> torch.Tensor:
+ self.freqs = self.freqs.to(indices.device)
+ phases = torch.outer(indices, self.freqs)
+ phases = torch.polar(torch.ones_like(phases), phases)
+ return phases
+
+ def _rotary_embedding(self, x: torch.Tensor, phases: torch.Tensor) -> torch.Tensor:
+ x_complex = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
+ x_rotated = x_complex * phases.unsqueeze(-2)
+ x_embed = torch.view_as_real(x_rotated).reshape(*x_rotated.shape[:-1], -1).to(x.dtype)
+ return x_embed
+
+ def forward(self, q: SparseTensor, k: Optional[SparseTensor] = None) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Args:
+ q (SparseTensor): [..., N, H, D] tensor of queries
+ k (SparseTensor): [..., N, H, D] tensor of keys
+ """
+ assert q.coords.shape[-1] == self.dim + 1, "Last dimension of coords must be equal to dim+1"
+ phases_cache_name = f'rope_phase_{self.dim}d_freq{self.rope_freq[0]}-{self.rope_freq[1]}_hd{self.head_dim}'
+ phases = q.get_spatial_cache(phases_cache_name)
+ if phases is None:
+ coords = q.coords[..., 1:]
+ phases = self._get_phases(coords.reshape(-1)).reshape(*coords.shape[:-1], -1)
+ if phases.shape[-1] < self.head_dim // 2:
+ padn = self.head_dim // 2 - phases.shape[-1]
+ phases = torch.cat([phases, torch.polar(
+ torch.ones(*phases.shape[:-1], padn, device=phases.device),
+ torch.zeros(*phases.shape[:-1], padn, device=phases.device)
+ )], dim=-1)
+ q.register_spatial_cache(phases_cache_name, phases)
+ q_embed = q.replace(self._rotary_embedding(q.feats, phases))
+ if k is None:
+ return q_embed
+ k_embed = k.replace(self._rotary_embedding(k.feats, phases))
+ return q_embed, k_embed
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/sparse/attention/windowed_attn.py b/TRELLIS.2/trellis2/modules/sparse/attention/windowed_attn.py
new file mode 100644
index 0000000000000000000000000000000000000000..043078899833e52ebf29d3ba1898cbd90e03f1d4
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/attention/windowed_attn.py
@@ -0,0 +1,190 @@
+from typing import *
+import torch
+import math
+from .. import SparseTensor
+from .. import config
+
+
+__all__ = [
+ 'sparse_windowed_scaled_dot_product_self_attention',
+ 'sparse_windowed_scaled_dot_product_cross_attention',
+]
+
+
+def calc_window_partition(
+ tensor: SparseTensor,
+ window_size: Union[int, Tuple[int, ...]],
+ shift_window: Union[int, Tuple[int, ...]] = 0,
+) -> Tuple[torch.Tensor, torch.Tensor, List[int], List[int]]:
+ """
+ Calculate serialization and partitioning for a set of coordinates.
+
+ Args:
+ tensor (SparseTensor): The input tensor.
+ window_size (int): The window size to use.
+ shift_window (Tuple[int, ...]): The shift of serialized coordinates.
+
+ Returns:
+ (torch.Tensor): Forwards indices.
+ (torch.Tensor): Backwards indices.
+ (torch.Tensor): Sequence lengths.
+ (dict): Attn func args.
+ """
+ DIM = tensor.coords.shape[1] - 1
+ shift_window = (shift_window,) * DIM if isinstance(shift_window, int) else shift_window
+ window_size = (window_size,) * DIM if isinstance(window_size, int) else window_size
+ shifted_coords = tensor.coords.clone().detach()
+ shifted_coords[:, 1:] += torch.tensor(shift_window, device=tensor.device, dtype=torch.int32).unsqueeze(0)
+
+ MAX_COORDS = [i + j for i, j in zip(tensor.spatial_shape, shift_window)]
+ NUM_WINDOWS = [math.ceil((mc + 1) / ws) for mc, ws in zip(MAX_COORDS, window_size)]
+ OFFSET = torch.cumprod(torch.tensor([1] + NUM_WINDOWS[::-1]), dim=0).tolist()[::-1]
+
+ shifted_coords[:, 1:] //= torch.tensor(window_size, device=tensor.device, dtype=torch.int32).unsqueeze(0)
+ shifted_indices = (shifted_coords * torch.tensor(OFFSET, device=tensor.device, dtype=torch.int32).unsqueeze(0)).sum(dim=1)
+ fwd_indices = torch.argsort(shifted_indices)
+ bwd_indices = torch.empty_like(fwd_indices)
+ bwd_indices[fwd_indices] = torch.arange(fwd_indices.shape[0], device=tensor.device)
+ seq_lens = torch.bincount(shifted_indices)
+ mask = seq_lens != 0
+ seq_lens = seq_lens[mask]
+
+ if config.ATTN == 'xformers':
+ if 'xops' not in globals():
+ import xformers.ops as xops
+ attn_func_args = {
+ 'attn_bias': xops.fmha.BlockDiagonalMask.from_seqlens(seq_lens)
+ }
+ elif config.ATTN == 'flash_attn':
+ attn_func_args = {
+ 'cu_seqlens': torch.cat([torch.tensor([0], device=tensor.device), torch.cumsum(seq_lens, dim=0)], dim=0).int(),
+ 'max_seqlen': torch.max(seq_lens)
+ }
+
+ return fwd_indices, bwd_indices, seq_lens, attn_func_args
+
+
+def sparse_windowed_scaled_dot_product_self_attention(
+ qkv: SparseTensor,
+ window_size: int,
+ shift_window: Tuple[int, int, int] = (0, 0, 0)
+) -> SparseTensor:
+ """
+ Apply windowed scaled dot product self attention to a sparse tensor.
+
+ Args:
+ qkv (SparseTensor): [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs.
+ window_size (int): The window size to use.
+ shift_window (Tuple[int, int, int]): The shift of serialized coordinates.
+
+ Returns:
+ (SparseTensor): [N, *, H, C] sparse tensor containing the output features.
+ """
+ assert len(qkv.shape) == 4 and qkv.shape[1] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, *, 3, H, C]"
+
+ serialization_spatial_cache_name = f'windowed_attention_{window_size}_{shift_window}'
+ serialization_spatial_cache = qkv.get_spatial_cache(serialization_spatial_cache_name)
+ if serialization_spatial_cache is None:
+ fwd_indices, bwd_indices, seq_lens, attn_func_args = calc_window_partition(qkv, window_size, shift_window)
+ qkv.register_spatial_cache(serialization_spatial_cache_name, (fwd_indices, bwd_indices, seq_lens, attn_func_args))
+ else:
+ fwd_indices, bwd_indices, seq_lens, attn_func_args = serialization_spatial_cache
+
+ qkv_feats = qkv.feats[fwd_indices] # [M, 3, H, C]
+
+ if config.DEBUG:
+ start = 0
+ qkv_coords = qkv.coords[fwd_indices]
+ for i in range(len(seq_lens)):
+ seq_coords = qkv_coords[start:start+seq_lens[i]]
+ assert (seq_coords[:, 1:].max(dim=0).values - seq_coords[:, 1:].min(dim=0).values < window_size).all(), \
+ f"SparseWindowedScaledDotProductSelfAttention: window size exceeded"
+ start += seq_lens[i]
+
+ if config.ATTN == 'xformers':
+ if 'xops' not in globals():
+ import xformers.ops as xops
+ q, k, v = qkv_feats.unbind(dim=1) # [M, H, C]
+ q = q.unsqueeze(0) # [1, M, H, C]
+ k = k.unsqueeze(0) # [1, M, H, C]
+ v = v.unsqueeze(0) # [1, M, H, C]
+ out = xops.memory_efficient_attention(q, k, v, **attn_func_args)[0] # [M, H, C]
+ elif config.ATTN == 'flash_attn':
+ if 'flash_attn' not in globals():
+ import flash_attn
+ out = flash_attn.flash_attn_varlen_qkvpacked_func(qkv_feats, **attn_func_args) # [M, H, C]
+
+ out = out[bwd_indices] # [T, H, C]
+
+ if config.DEBUG:
+ qkv_coords = qkv_coords[bwd_indices]
+ assert torch.equal(qkv_coords, qkv.coords), "SparseWindowedScaledDotProductSelfAttention: coordinate mismatch"
+
+ return qkv.replace(out)
+
+
+def sparse_windowed_scaled_dot_product_cross_attention(
+ q: SparseTensor,
+ kv: SparseTensor,
+ q_window_size: int,
+ kv_window_size: int,
+ q_shift_window: Tuple[int, int, int] = (0, 0, 0),
+ kv_shift_window: Tuple[int, int, int] = (0, 0, 0),
+) -> SparseTensor:
+ """
+ Apply windowed scaled dot product cross attention to two sparse tensors.
+
+ Args:
+ q (SparseTensor): [N, *, H, C] sparse tensor containing Qs.
+ kv (SparseTensor): [N, *, 2, H, C] sparse tensor containing Ks and Vs.
+ q_window_size (int): The window size to use for Qs.
+ kv_window_size (int): The window size to use for Ks and Vs.
+ q_shift_window (Tuple[int, int, int]): The shift of serialized coordinates for Qs.
+ kv_shift_window (Tuple[int, int, int]): The shift of serialized coordinates for Ks and Vs.
+
+ Returns:
+ (SparseTensor): [N, *, H, C] sparse tensor containing the output features.
+ """
+ assert len(q.shape) == 3, f"Invalid shape for q, got {q.shape}, expected [N, *, H, C]"
+ assert len(kv.shape) == 4 and kv.shape[1] == 2, f"Invalid shape for kv, got {kv.shape}, expected [N, *, 2, H, C]"
+
+ q_serialization_spatial_cache_name = f'windowed_attention_{q_window_size}_{q_shift_window}'
+ q_serialization_spatial_cache = q.get_spatial_cache(q_serialization_spatial_cache_name)
+ if q_serialization_spatial_cache is None:
+ q_fwd_indices, q_bwd_indices, q_seq_lens, q_attn_func_args = calc_window_partition(q, q_window_size, q_shift_window)
+ q.register_spatial_cache(q_serialization_spatial_cache_name, (q_fwd_indices, q_bwd_indices, q_seq_lens, q_attn_func_args))
+ else:
+ q_fwd_indices, q_bwd_indices, q_seq_lens, q_attn_func_args = q_serialization_spatial_cache
+ kv_serialization_spatial_cache_name = f'windowed_attention_{kv_window_size}_{kv_shift_window}'
+ kv_serialization_spatial_cache = kv.get_spatial_cache(kv_serialization_spatial_cache_name)
+ if kv_serialization_spatial_cache is None:
+ kv_fwd_indices, kv_bwd_indices, kv_seq_lens, kv_attn_func_args = calc_window_partition(kv, kv_window_size, kv_shift_window)
+ kv.register_spatial_cache(kv_serialization_spatial_cache_name, (kv_fwd_indices, kv_bwd_indices, kv_seq_lens, kv_attn_func_args))
+ else:
+ kv_fwd_indices, kv_bwd_indices, kv_seq_lens, kv_attn_func_args = kv_serialization_spatial_cache
+
+ assert len(q_seq_lens) == len(kv_seq_lens), "Number of sequences in q and kv must match"
+
+ q_feats = q.feats[q_fwd_indices] # [M, H, C]
+ kv_feats = kv.feats[kv_fwd_indices] # [M, 2, H, C]
+
+ if config.ATTN == 'xformers':
+ if 'xops' not in globals():
+ import xformers.ops as xops
+ k, v = kv_feats.unbind(dim=1) # [M, H, C]
+ q = q.unsqueeze(0) # [1, M, H, C]
+ k = k.unsqueeze(0) # [1, M, H, C]
+ v = v.unsqueeze(0) # [1, M, H, C]
+ mask = xops.fmha.BlockDiagonalMask.from_seqlens(q_seq_lens, kv_seq_lens)
+ out = xops.memory_efficient_attention(q, k, v, attn_bias=mask)[0] # [M, H, C]
+ elif config.ATTN == 'flash_attn':
+ if 'flash_attn' not in globals():
+ import flash_attn
+ out = flash_attn.flash_attn_varlen_kvpacked_func(q_feats, kv_feats,
+ cu_seqlens_q=q_attn_func_args['cu_seqlens'], cu_seqlens_k=kv_attn_func_args['cu_seqlens'],
+ max_seqlen_q=q_attn_func_args['max_seqlen'], max_seqlen_k=kv_attn_func_args['max_seqlen'],
+ ) # [M, H, C]
+
+ out = out[q_bwd_indices] # [T, H, C]
+
+ return q.replace(out)
diff --git a/TRELLIS.2/trellis2/modules/sparse/basic.py b/TRELLIS.2/trellis2/modules/sparse/basic.py
new file mode 100644
index 0000000000000000000000000000000000000000..880973b8dd6bdafcfca4ca7c529308d2ef2ad266
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/basic.py
@@ -0,0 +1,836 @@
+from typing import *
+from fractions import Fraction
+import torch
+from . import config
+
+
+__all__ = [
+ 'VarLenTensor',
+ 'varlen_cat',
+ 'varlen_unbind',
+ 'SparseTensor',
+ 'sparse_cat',
+ 'sparse_unbind',
+]
+
+
+class VarLenTensor:
+ """
+ Sequential tensor with variable length.
+
+ Args:
+ feats (torch.Tensor): Features of the varlen tensor.
+ layout (List[slice]): Layout of the varlen tensor for each batch
+ """
+ def __init__(self, feats: torch.Tensor, layout: List[slice]=None):
+ self.feats = feats
+ self.layout = layout if layout is not None else [slice(0, feats.shape[0])]
+ self._cache = {}
+
+ @staticmethod
+ def layout_from_seqlen(seqlen: list) -> List[slice]:
+ """
+ Create a layout from a tensor of sequence lengths.
+ """
+ layout = []
+ start = 0
+ for l in seqlen:
+ layout.append(slice(start, start + l))
+ start += l
+ return layout
+
+ @staticmethod
+ def from_tensor_list(tensor_list: List[torch.Tensor]) -> 'VarLenTensor':
+ """
+ Create a VarLenTensor from a list of tensors.
+ """
+ feats = torch.cat(tensor_list, dim=0)
+ layout = []
+ start = 0
+ for tensor in tensor_list:
+ layout.append(slice(start, start + tensor.shape[0]))
+ start += tensor.shape[0]
+ return VarLenTensor(feats, layout)
+
+ def to_tensor_list(self) -> List[torch.Tensor]:
+ """
+ Convert a VarLenTensor to a list of tensors.
+ """
+ tensor_list = []
+ for s in self.layout:
+ tensor_list.append(self.feats[s])
+ return tensor_list
+
+ def __len__(self) -> int:
+ return len(self.layout)
+
+ @property
+ def shape(self) -> torch.Size:
+ return torch.Size([len(self.layout), *self.feats.shape[1:]])
+
+ def dim(self) -> int:
+ return len(self.shape)
+
+ @property
+ def ndim(self) -> int:
+ return self.dim()
+
+ @property
+ def dtype(self):
+ return self.feats.dtype
+
+ @property
+ def device(self):
+ return self.feats.device
+
+ @property
+ def seqlen(self) -> torch.LongTensor:
+ if 'seqlen' not in self._cache:
+ self._cache['seqlen'] = torch.tensor([l.stop - l.start for l in self.layout], dtype=torch.long, device=self.device)
+ return self._cache['seqlen']
+
+ @property
+ def cum_seqlen(self) -> torch.LongTensor:
+ if 'cum_seqlen' not in self._cache:
+ self._cache['cum_seqlen'] = torch.cat([
+ torch.tensor([0], dtype=torch.long, device=self.device),
+ self.seqlen.cumsum(dim=0)
+ ], dim=0)
+ return self._cache['cum_seqlen']
+
+ @property
+ def batch_boardcast_map(self) -> torch.LongTensor:
+ """
+ Get the broadcast map for the varlen tensor.
+ """
+ if 'batch_boardcast_map' not in self._cache:
+ self._cache['batch_boardcast_map'] = torch.repeat_interleave(
+ torch.arange(len(self.layout), device=self.device),
+ self.seqlen,
+ )
+ return self._cache['batch_boardcast_map']
+
+ @overload
+ def to(self, dtype: torch.dtype, *, non_blocking: bool = False, copy: bool = False) -> 'VarLenTensor': ...
+
+ @overload
+ def to(self, device: Optional[Union[str, torch.device]] = None, dtype: Optional[torch.dtype] = None, *, non_blocking: bool = False, copy: bool = False) -> 'VarLenTensor': ...
+
+ def to(self, *args, **kwargs) -> 'VarLenTensor':
+ device = None
+ dtype = None
+ if len(args) == 2:
+ device, dtype = args
+ elif len(args) == 1:
+ if isinstance(args[0], torch.dtype):
+ dtype = args[0]
+ else:
+ device = args[0]
+ if 'dtype' in kwargs:
+ assert dtype is None, "to() received multiple values for argument 'dtype'"
+ dtype = kwargs['dtype']
+ if 'device' in kwargs:
+ assert device is None, "to() received multiple values for argument 'device'"
+ device = kwargs['device']
+ non_blocking = kwargs.get('non_blocking', False)
+ copy = kwargs.get('copy', False)
+
+ new_feats = self.feats.to(device=device, dtype=dtype, non_blocking=non_blocking, copy=copy)
+ return self.replace(new_feats)
+
+ def type(self, dtype):
+ new_feats = self.feats.type(dtype)
+ return self.replace(new_feats)
+
+ def cpu(self) -> 'VarLenTensor':
+ new_feats = self.feats.cpu()
+ return self.replace(new_feats)
+
+ def cuda(self) -> 'VarLenTensor':
+ new_feats = self.feats.cuda()
+ return self.replace(new_feats)
+
+ def half(self) -> 'VarLenTensor':
+ new_feats = self.feats.half()
+ return self.replace(new_feats)
+
+ def float(self) -> 'VarLenTensor':
+ new_feats = self.feats.float()
+ return self.replace(new_feats)
+
+ def detach(self) -> 'VarLenTensor':
+ new_feats = self.feats.detach()
+ return self.replace(new_feats)
+
+ def reshape(self, *shape) -> 'VarLenTensor':
+ new_feats = self.feats.reshape(self.feats.shape[0], *shape)
+ return self.replace(new_feats)
+
+ def unbind(self, dim: int) -> List['VarLenTensor']:
+ return varlen_unbind(self, dim)
+
+ def replace(self, feats: torch.Tensor) -> 'VarLenTensor':
+ new_tensor = VarLenTensor(
+ feats=feats,
+ layout=self.layout,
+ )
+ new_tensor._cache = self._cache
+ return new_tensor
+
+ def to_dense(self, max_length=None) -> torch.Tensor:
+ """
+ Convert a VarLenTensor to a dense representation without for-loop.
+
+ Returns:
+ dense (torch.Tensor): (N, L, C) dense tensor
+ mask (torch.BoolTensor): (N, L) mask indicating valid positions
+ """
+ N = len(self)
+ L = max_length or self.seqlen.max().item()
+ spatial = self.feats.shape[1:]
+ idx = torch.arange(L, device=self.device).unsqueeze(0).expand(N, L)
+ mask = (idx < self.seqlen.unsqueeze(1))
+ mapping = mask.reshape(-1).cumsum(dim=0) - 1
+ dense = self.feats[mapping]
+ dense = dense.reshape(N, L, *spatial)
+ return dense, mask
+
+ def __neg__(self) -> 'VarLenTensor':
+ return self.replace(-self.feats)
+
+ def __elemwise__(self, other: Union[torch.Tensor, 'VarLenTensor'], op: callable) -> 'VarLenTensor':
+ if isinstance(other, torch.Tensor):
+ try:
+ other = torch.broadcast_to(other, self.shape)
+ other = other[self.batch_boardcast_map]
+ except:
+ pass
+ if isinstance(other, VarLenTensor):
+ other = other.feats
+ new_feats = op(self.feats, other)
+ new_tensor = self.replace(new_feats)
+ return new_tensor
+
+ def __add__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.add)
+
+ def __radd__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.add)
+
+ def __sub__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.sub)
+
+ def __rsub__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, lambda x, y: torch.sub(y, x))
+
+ def __mul__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.mul)
+
+ def __rmul__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.mul)
+
+ def __truediv__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, torch.div)
+
+ def __rtruediv__(self, other: Union[torch.Tensor, 'VarLenTensor', float]) -> 'VarLenTensor':
+ return self.__elemwise__(other, lambda x, y: torch.div(y, x))
+
+ def __getitem__(self, idx):
+ if isinstance(idx, int):
+ idx = [idx]
+ elif isinstance(idx, slice):
+ idx = range(*idx.indices(self.shape[0]))
+ elif isinstance(idx, list):
+ assert all(isinstance(i, int) for i in idx), f"Only integer indices are supported: {idx}"
+ elif isinstance(idx, torch.Tensor):
+ if idx.dtype == torch.bool:
+ assert idx.shape == (self.shape[0],), f"Invalid index shape: {idx.shape}"
+ idx = idx.nonzero().squeeze(1)
+ elif idx.dtype in [torch.int32, torch.int64]:
+ assert len(idx.shape) == 1, f"Invalid index shape: {idx.shape}"
+ else:
+ raise ValueError(f"Unknown index type: {idx.dtype}")
+ else:
+ raise ValueError(f"Unknown index type: {type(idx)}")
+
+ new_feats = []
+ new_layout = []
+ start = 0
+ for new_idx, old_idx in enumerate(idx):
+ new_feats.append(self.feats[self.layout[old_idx]])
+ new_layout.append(slice(start, start + len(new_feats[-1])))
+ start += len(new_feats[-1])
+ new_feats = torch.cat(new_feats, dim=0).contiguous()
+ new_tensor = VarLenTensor(feats=new_feats, layout=new_layout)
+ return new_tensor
+
+ def reduce(self, op: str, dim: Optional[Union[int, Tuple[int,...]]] = None, keepdim: bool = False) -> torch.Tensor:
+ if isinstance(dim, int):
+ dim = (dim,)
+
+ if op =='mean':
+ red = self.feats.mean(dim=dim, keepdim=keepdim)
+ elif op =='sum':
+ red = self.feats.sum(dim=dim, keepdim=keepdim)
+ elif op == 'prod':
+ red = self.feats.prod(dim=dim, keepdim=keepdim)
+ else:
+ raise ValueError(f"Unsupported reduce operation: {op}")
+
+ if dim is None or 0 in dim:
+ return red
+
+ red = torch.segment_reduce(red, reduce=op, lengths=self.seqlen)
+ return red
+
+ def mean(self, dim: Optional[Union[int, Tuple[int,...]]] = None, keepdim: bool = False) -> torch.Tensor:
+ return self.reduce(op='mean', dim=dim, keepdim=keepdim)
+
+ def sum(self, dim: Optional[Union[int, Tuple[int,...]]] = None, keepdim: bool = False) -> torch.Tensor:
+ return self.reduce(op='sum', dim=dim, keepdim=keepdim)
+
+ def prod(self, dim: Optional[Union[int, Tuple[int,...]]] = None, keepdim: bool = False) -> torch.Tensor:
+ return self.reduce(op='prod', dim=dim, keepdim=keepdim)
+
+ def std(self, dim: Optional[Union[int, Tuple[int,...]]] = None, keepdim: bool = False) -> torch.Tensor:
+ mean = self.mean(dim=dim, keepdim=True)
+ mean2 = self.replace(self.feats ** 2).mean(dim=dim, keepdim=True)
+ std = (mean2 - mean ** 2).sqrt()
+ return std
+
+ def __repr__(self) -> str:
+ return f"VarLenTensor(shape={self.shape}, dtype={self.dtype}, device={self.device})"
+
+
+def varlen_cat(inputs: List[VarLenTensor], dim: int = 0) -> VarLenTensor:
+ """
+ Concatenate a list of varlen tensors.
+
+ Args:
+ inputs (List[VarLenTensor]): List of varlen tensors to concatenate.
+ """
+ if dim == 0:
+ new_feats = torch.cat([input.feats for input in inputs], dim=0)
+ start = 0
+ new_layout = []
+ for input in inputs:
+ for l in input.layout:
+ new_layout.append(slice(start, start + l.stop - l.start))
+ start += l.stop - l.start
+ output = VarLenTensor(feats=new_feats, layout=new_layout)
+ else:
+ feats = torch.cat([input.feats for input in inputs], dim=dim)
+ output = inputs[0].replace(feats)
+
+ return output
+
+
+def varlen_unbind(input: VarLenTensor, dim: int) -> Union[List[VarLenTensor]]:
+ """
+ Unbind a varlen tensor along a dimension.
+
+ Args:
+ input (VarLenTensor): Varlen tensor to unbind.
+ dim (int): Dimension to unbind.
+ """
+ if dim == 0:
+ return [input[i] for i in range(len(input))]
+ else:
+ feats = input.feats.unbind(dim)
+ return [input.replace(f) for f in feats]
+
+
+class SparseTensor(VarLenTensor):
+ """
+ Sparse tensor with support for both torchsparse and spconv backends.
+
+ Parameters:
+ - feats (torch.Tensor): Features of the sparse tensor.
+ - coords (torch.Tensor): Coordinates of the sparse tensor.
+ - shape (torch.Size): Shape of the sparse tensor.
+ - layout (List[slice]): Layout of the sparse tensor for each batch
+ - data (SparseTensorData): Sparse tensor data used for convolusion
+
+ NOTE:
+ - Data corresponding to a same batch should be contiguous.
+ - Coords should be in [0, 1023]
+ """
+ SparseTensorData = None
+
+ @overload
+ def __init__(self, feats: torch.Tensor, coords: torch.Tensor, shape: Optional[torch.Size] = None, **kwargs): ...
+
+ @overload
+ def __init__(self, data, shape: Optional[torch.Size] = None, **kwargs): ...
+
+ def __init__(self, *args, **kwargs):
+ # Lazy import of sparse tensor backend
+ if self.SparseTensorData is None:
+ import importlib
+ if config.CONV == 'torchsparse':
+ self.SparseTensorData = importlib.import_module('torchsparse').SparseTensor
+ elif config.CONV == 'spconv':
+ self.SparseTensorData = importlib.import_module('spconv.pytorch').SparseConvTensor
+
+ method_id = 0
+ if len(args) != 0:
+ method_id = 0 if isinstance(args[0], torch.Tensor) else 1
+ else:
+ method_id = 1 if 'data' in kwargs else 0
+
+ if method_id == 0:
+ feats, coords, shape = args + (None,) * (3 - len(args))
+ if 'feats' in kwargs:
+ feats = kwargs['feats']
+ del kwargs['feats']
+ if 'coords' in kwargs:
+ coords = kwargs['coords']
+ del kwargs['coords']
+ if 'shape' in kwargs:
+ shape = kwargs['shape']
+ del kwargs['shape']
+
+ if config.CONV == 'torchsparse':
+ self.data = self.SparseTensorData(feats, coords, **kwargs)
+ elif config.CONV == 'spconv':
+ spatial_shape = list(coords.max(0)[0] + 1)
+ self.data = self.SparseTensorData(feats.reshape(feats.shape[0], -1), coords, spatial_shape[1:], spatial_shape[0], **kwargs)
+ self.data._features = feats
+ else:
+ self.data = {
+ 'feats': feats,
+ 'coords': coords,
+ }
+ elif method_id == 1:
+ data, shape = args + (None,) * (2 - len(args))
+ if 'data' in kwargs:
+ data = kwargs['data']
+ del kwargs['data']
+ if 'shape' in kwargs:
+ shape = kwargs['shape']
+ del kwargs['shape']
+
+ self.data = data
+
+ self._shape = shape
+ self._scale = kwargs.get('scale', (Fraction(1, 1), Fraction(1, 1), Fraction(1, 1)))
+ self._spatial_cache = kwargs.get('spatial_cache', {})
+
+ if config.DEBUG:
+ try:
+ assert self.feats.shape[0] == self.coords.shape[0], f"Invalid feats shape: {self.feats.shape}, coords shape: {self.coords.shape}"
+ assert self.shape == self.__cal_shape(self.feats, self.coords), f"Invalid shape: {self.shape}"
+ assert self.layout == self.__cal_layout(self.coords, self.shape[0]), f"Invalid layout: {self.layout}"
+ for i in range(self.shape[0]):
+ assert torch.all(self.coords[self.layout[i], 0] == i), f"The data of batch {i} is not contiguous"
+ except Exception as e:
+ print('Debugging information:')
+ print(f"- Shape: {self.shape}")
+ print(f"- Layout: {self.layout}")
+ print(f"- Scale: {self._scale}")
+ print(f"- Coords: {self.coords}")
+ raise e
+
+ @staticmethod
+ def from_tensor_list(feats_list: List[torch.Tensor], coords_list: List[torch.Tensor]) -> 'SparseTensor':
+ """
+ Create a SparseTensor from a list of tensors.
+ """
+ feats = torch.cat(feats_list, dim=0)
+ coords = []
+ for i, coord in enumerate(coords_list):
+ coord = torch.cat([torch.full_like(coord[:, :1], i), coord[:, 1:]], dim=1)
+ coords.append(coord)
+ coords = torch.cat(coords, dim=0)
+ return SparseTensor(feats, coords)
+
+ def to_tensor_list(self) -> Tuple[List[torch.Tensor], List[torch.Tensor]]:
+ """
+ Convert a SparseTensor to list of tensors.
+ """
+ feats_list = []
+ coords_list = []
+ for s in self.layout:
+ feats_list.append(self.feats[s])
+ coords_list.append(self.coords[s])
+ return feats_list, coords_list
+
+ def __len__(self) -> int:
+ return len(self.layout)
+
+ def __cal_shape(self, feats, coords):
+ shape = []
+ shape.append(coords[:, 0].max().item() + 1)
+ shape.extend([*feats.shape[1:]])
+ return torch.Size(shape)
+
+ def __cal_layout(self, coords, batch_size):
+ seq_len = torch.bincount(coords[:, 0], minlength=batch_size)
+ offset = torch.cumsum(seq_len, dim=0)
+ layout = [slice((offset[i] - seq_len[i]).item(), offset[i].item()) for i in range(batch_size)]
+ return layout
+
+ def __cal_spatial_shape(self, coords):
+ return torch.Size((coords[:, 1:].max(0)[0] + 1).tolist())
+
+ @property
+ def shape(self) -> torch.Size:
+ if self._shape is None:
+ self._shape = self.__cal_shape(self.feats, self.coords)
+ return self._shape
+
+ @property
+ def layout(self) -> List[slice]:
+ layout = self.get_spatial_cache('layout')
+ if layout is None:
+ layout = self.__cal_layout(self.coords, self.shape[0])
+ self.register_spatial_cache('layout', layout)
+ return layout
+
+ @property
+ def spatial_shape(self) -> torch.Size:
+ spatial_shape = self.get_spatial_cache('shape')
+ if spatial_shape is None:
+ spatial_shape = self.__cal_spatial_shape(self.coords)
+ self.register_spatial_cache('shape', spatial_shape)
+ return spatial_shape
+
+ @property
+ def feats(self) -> torch.Tensor:
+ if config.CONV == 'torchsparse':
+ return self.data.F
+ elif config.CONV == 'spconv':
+ return self.data.features
+ else:
+ return self.data['feats']
+
+ @feats.setter
+ def feats(self, value: torch.Tensor):
+ if config.CONV == 'torchsparse':
+ self.data.F = value
+ elif config.CONV == 'spconv':
+ self.data.features = value
+ else:
+ self.data['feats'] = value
+
+ @property
+ def coords(self) -> torch.Tensor:
+ if config.CONV == 'torchsparse':
+ return self.data.C
+ elif config.CONV == 'spconv':
+ return self.data.indices
+ else:
+ return self.data['coords']
+
+ @coords.setter
+ def coords(self, value: torch.Tensor):
+ if config.CONV == 'torchsparse':
+ self.data.C = value
+ elif config.CONV == 'spconv':
+ self.data.indices = value
+ else:
+ self.data['coords'] = value
+
+ @property
+ def dtype(self):
+ return self.feats.dtype
+
+ @property
+ def device(self):
+ return self.feats.device
+
+ @property
+ def seqlen(self) -> torch.LongTensor:
+ seqlen = self.get_spatial_cache('seqlen')
+ if seqlen is None:
+ seqlen = torch.tensor([l.stop - l.start for l in self.layout], dtype=torch.long, device=self.device)
+ self.register_spatial_cache('seqlen', seqlen)
+ return seqlen
+
+ @property
+ def cum_seqlen(self) -> torch.LongTensor:
+ cum_seqlen = self.get_spatial_cache('cum_seqlen')
+ if cum_seqlen is None:
+ cum_seqlen = torch.cat([
+ torch.tensor([0], dtype=torch.long, device=self.device),
+ self.seqlen.cumsum(dim=0)
+ ], dim=0)
+ self.register_spatial_cache('cum_seqlen', cum_seqlen)
+ return cum_seqlen
+
+ @property
+ def batch_boardcast_map(self) -> torch.LongTensor:
+ """
+ Get the broadcast map for the varlen tensor.
+ """
+ batch_boardcast_map = self.get_spatial_cache('batch_boardcast_map')
+ if batch_boardcast_map is None:
+ batch_boardcast_map = torch.repeat_interleave(
+ torch.arange(len(self.layout), device=self.device),
+ self.seqlen,
+ )
+ self.register_spatial_cache('batch_boardcast_map', batch_boardcast_map)
+ return batch_boardcast_map
+
+ @overload
+ def to(self, dtype: torch.dtype, *, non_blocking: bool = False, copy: bool = False) -> 'SparseTensor': ...
+
+ @overload
+ def to(self, device: Optional[Union[str, torch.device]] = None, dtype: Optional[torch.dtype] = None, *, non_blocking: bool = False, copy: bool = False) -> 'SparseTensor': ...
+
+ def to(self, *args, **kwargs) -> 'SparseTensor':
+ device = None
+ dtype = None
+ if len(args) == 2:
+ device, dtype = args
+ elif len(args) == 1:
+ if isinstance(args[0], torch.dtype):
+ dtype = args[0]
+ else:
+ device = args[0]
+ if 'dtype' in kwargs:
+ assert dtype is None, "to() received multiple values for argument 'dtype'"
+ dtype = kwargs['dtype']
+ if 'device' in kwargs:
+ assert device is None, "to() received multiple values for argument 'device'"
+ device = kwargs['device']
+ non_blocking = kwargs.get('non_blocking', False)
+ copy = kwargs.get('copy', False)
+
+ new_feats = self.feats.to(device=device, dtype=dtype, non_blocking=non_blocking, copy=copy)
+ new_coords = self.coords.to(device=device, non_blocking=non_blocking, copy=copy)
+ return self.replace(new_feats, new_coords)
+
+ def type(self, dtype):
+ new_feats = self.feats.type(dtype)
+ return self.replace(new_feats)
+
+ def cpu(self) -> 'SparseTensor':
+ new_feats = self.feats.cpu()
+ new_coords = self.coords.cpu()
+ return self.replace(new_feats, new_coords)
+
+ def cuda(self) -> 'SparseTensor':
+ new_feats = self.feats.cuda()
+ new_coords = self.coords.cuda()
+ return self.replace(new_feats, new_coords)
+
+ def half(self) -> 'SparseTensor':
+ new_feats = self.feats.half()
+ return self.replace(new_feats)
+
+ def float(self) -> 'SparseTensor':
+ new_feats = self.feats.float()
+ return self.replace(new_feats)
+
+ def detach(self) -> 'SparseTensor':
+ new_coords = self.coords.detach()
+ new_feats = self.feats.detach()
+ return self.replace(new_feats, new_coords)
+
+ def reshape(self, *shape) -> 'SparseTensor':
+ new_feats = self.feats.reshape(self.feats.shape[0], *shape)
+ return self.replace(new_feats)
+
+ def unbind(self, dim: int) -> List['SparseTensor']:
+ return sparse_unbind(self, dim)
+
+ def replace(self, feats: torch.Tensor, coords: Optional[torch.Tensor] = None) -> 'SparseTensor':
+ if config.CONV == 'torchsparse':
+ new_data = self.SparseTensorData(
+ feats=feats,
+ coords=self.data.coords if coords is None else coords,
+ stride=self.data.stride,
+ spatial_range=self.data.spatial_range,
+ )
+ new_data._caches = self.data._caches
+ elif config.CONV == 'spconv':
+ new_data = self.SparseTensorData(
+ self.data.features.reshape(self.data.features.shape[0], -1),
+ self.data.indices,
+ self.data.spatial_shape,
+ self.data.batch_size,
+ self.data.grid,
+ self.data.voxel_num,
+ self.data.indice_dict
+ )
+ new_data._features = feats
+ new_data.benchmark = self.data.benchmark
+ new_data.benchmark_record = self.data.benchmark_record
+ new_data.thrust_allocator = self.data.thrust_allocator
+ new_data._timer = self.data._timer
+ new_data.force_algo = self.data.force_algo
+ new_data.int8_scale = self.data.int8_scale
+ if coords is not None:
+ new_data.indices = coords
+ else:
+ new_data = {
+ 'feats': feats,
+ 'coords': self.data['coords'] if coords is None else coords,
+ }
+ new_tensor = SparseTensor(
+ new_data,
+ shape=torch.Size([self._shape[0]] + list(feats.shape[1:])) if self._shape is not None else None,
+ scale=self._scale,
+ spatial_cache=self._spatial_cache
+ )
+ return new_tensor
+
+ def to_dense(self) -> torch.Tensor:
+ if config.CONV == 'torchsparse':
+ return self.data.dense()
+ elif config.CONV == 'spconv':
+ return self.data.dense()
+ else:
+ spatial_shape = self.spatial_shape
+ ret = torch.zeros(*self.shape, *spatial_shape, dtype=self.dtype, device=self.device)
+ idx = [self.coords[:, 0], slice(None)] + self.coords[:, 1:].unbind(1)
+ ret[tuple(idx)] = self.feats
+ return ret
+
+ @staticmethod
+ def full(aabb, dim, value, dtype=torch.float32, device=None) -> 'SparseTensor':
+ N, C = dim
+ x = torch.arange(aabb[0], aabb[3] + 1)
+ y = torch.arange(aabb[1], aabb[4] + 1)
+ z = torch.arange(aabb[2], aabb[5] + 1)
+ coords = torch.stack(torch.meshgrid(x, y, z, indexing='ij'), dim=-1).reshape(-1, 3)
+ coords = torch.cat([
+ torch.arange(N).view(-1, 1).repeat(1, coords.shape[0]).view(-1, 1),
+ coords.repeat(N, 1),
+ ], dim=1).to(dtype=torch.int32, device=device)
+ feats = torch.full((coords.shape[0], C), value, dtype=dtype, device=device)
+ return SparseTensor(feats=feats, coords=coords)
+
+ def __merge_sparse_cache(self, other: 'SparseTensor') -> dict:
+ new_cache = {}
+ for k in set(list(self._spatial_cache.keys()) + list(other._spatial_cache.keys())):
+ if k in self._spatial_cache:
+ new_cache[k] = self._spatial_cache[k]
+ if k in other._spatial_cache:
+ if k not in new_cache:
+ new_cache[k] = other._spatial_cache[k]
+ else:
+ new_cache[k].update(other._spatial_cache[k])
+ return new_cache
+
+ def __elemwise__(self, other: Union[torch.Tensor, VarLenTensor], op: callable) -> 'SparseTensor':
+ if isinstance(other, torch.Tensor):
+ try:
+ other = torch.broadcast_to(other, self.shape)
+ other = other[self.batch_boardcast_map]
+ except:
+ pass
+ if isinstance(other, VarLenTensor):
+ other = other.feats
+ new_feats = op(self.feats, other)
+ new_tensor = self.replace(new_feats)
+ if isinstance(other, SparseTensor):
+ new_tensor._spatial_cache = self.__merge_sparse_cache(other)
+ return new_tensor
+
+ def __getitem__(self, idx):
+ if isinstance(idx, int):
+ idx = [idx]
+ elif isinstance(idx, slice):
+ idx = range(*idx.indices(self.shape[0]))
+ elif isinstance(idx, list):
+ assert all(isinstance(i, int) for i in idx), f"Only integer indices are supported: {idx}"
+ elif isinstance(idx, torch.Tensor):
+ if idx.dtype == torch.bool:
+ assert idx.shape == (self.shape[0],), f"Invalid index shape: {idx.shape}"
+ idx = idx.nonzero().squeeze(1)
+ elif idx.dtype in [torch.int32, torch.int64]:
+ assert len(idx.shape) == 1, f"Invalid index shape: {idx.shape}"
+ else:
+ raise ValueError(f"Unknown index type: {idx.dtype}")
+ else:
+ raise ValueError(f"Unknown index type: {type(idx)}")
+
+ new_coords = []
+ new_feats = []
+ new_layout = []
+ new_shape = torch.Size([len(idx)] + list(self.shape[1:]))
+ start = 0
+ for new_idx, old_idx in enumerate(idx):
+ new_coords.append(self.coords[self.layout[old_idx]].clone())
+ new_coords[-1][:, 0] = new_idx
+ new_feats.append(self.feats[self.layout[old_idx]])
+ new_layout.append(slice(start, start + len(new_coords[-1])))
+ start += len(new_coords[-1])
+ new_coords = torch.cat(new_coords, dim=0).contiguous()
+ new_feats = torch.cat(new_feats, dim=0).contiguous()
+ new_tensor = SparseTensor(feats=new_feats, coords=new_coords, shape=new_shape)
+ new_tensor.register_spatial_cache('layout', new_layout)
+ return new_tensor
+
+ def clear_spatial_cache(self) -> None:
+ """
+ Clear all spatial caches.
+ """
+ self._spatial_cache = {}
+
+ def register_spatial_cache(self, key, value) -> None:
+ """
+ Register a spatial cache.
+ The spatial cache can be any thing you want to cache.
+ The registery and retrieval of the cache is based on current scale.
+ """
+ scale_key = str(self._scale)
+ if scale_key not in self._spatial_cache:
+ self._spatial_cache[scale_key] = {}
+ self._spatial_cache[scale_key][key] = value
+
+ def get_spatial_cache(self, key=None):
+ """
+ Get a spatial cache.
+ """
+ scale_key = str(self._scale)
+ cur_scale_cache = self._spatial_cache.get(scale_key, {})
+ if key is None:
+ return cur_scale_cache
+ return cur_scale_cache.get(key, None)
+
+ def __repr__(self) -> str:
+ return f"SparseTensor(shape={self.shape}, dtype={self.dtype}, device={self.device})"
+
+def sparse_cat(inputs: List[SparseTensor], dim: int = 0) -> SparseTensor:
+ """
+ Concatenate a list of sparse tensors.
+
+ Args:
+ inputs (List[SparseTensor]): List of sparse tensors to concatenate.
+ """
+ if dim == 0:
+ start = 0
+ coords = []
+ for input in inputs:
+ coords.append(input.coords.clone())
+ coords[-1][:, 0] += start
+ start += input.shape[0]
+ coords = torch.cat(coords, dim=0)
+ feats = torch.cat([input.feats for input in inputs], dim=0)
+ output = SparseTensor(
+ coords=coords,
+ feats=feats,
+ )
+ else:
+ feats = torch.cat([input.feats for input in inputs], dim=dim)
+ output = inputs[0].replace(feats)
+
+ return output
+
+
+def sparse_unbind(input: SparseTensor, dim: int) -> List[SparseTensor]:
+ """
+ Unbind a sparse tensor along a dimension.
+
+ Args:
+ input (SparseTensor): Sparse tensor to unbind.
+ dim (int): Dimension to unbind.
+ """
+ if dim == 0:
+ return [input[i] for i in range(input.shape[0])]
+ else:
+ feats = input.feats.unbind(dim)
+ return [input.replace(f) for f in feats]
diff --git a/TRELLIS.2/trellis2/modules/sparse/config.py b/TRELLIS.2/trellis2/modules/sparse/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..a5f4d532316efcf989ab70b9b5218ba962bafe07
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/config.py
@@ -0,0 +1,43 @@
+from typing import *
+
+CONV = 'flex_gemm'
+DEBUG = False
+ATTN = 'flash_attn'
+
+def __from_env():
+ import os
+
+ global CONV
+ global DEBUG
+ global ATTN
+
+ env_sparse_conv_backend = os.environ.get('SPARSE_CONV_BACKEND')
+ env_sparse_debug = os.environ.get('SPARSE_DEBUG')
+ env_sparse_attn_backend = os.environ.get('SPARSE_ATTN_BACKEND')
+ if env_sparse_attn_backend is None:
+ env_sparse_attn_backend = os.environ.get('ATTN_BACKEND')
+
+ if env_sparse_conv_backend is not None and env_sparse_conv_backend in ['none', 'spconv', 'torchsparse', 'flex_gemm']:
+ CONV = env_sparse_conv_backend
+ if env_sparse_debug is not None:
+ DEBUG = env_sparse_debug == '1'
+ if env_sparse_attn_backend is not None and env_sparse_attn_backend in ['xformers', 'flash_attn', 'flash_attn_3']:
+ ATTN = env_sparse_attn_backend
+
+ print(f"[SPARSE] Conv backend: {CONV}; Attention backend: {ATTN}")
+
+
+__from_env()
+
+
+def set_conv_backend(backend: Literal['none', 'spconv', 'torchsparse', 'flex_gemm']):
+ global CONV
+ CONV = backend
+
+def set_debug(debug: bool):
+ global DEBUG
+ DEBUG = debug
+
+def set_attn_backend(backend: Literal['xformers', 'flash_attn']):
+ global ATTN
+ ATTN = backend
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/__init__.py b/TRELLIS.2/trellis2/modules/sparse/conv/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a7f5911f2cb266f93e52cfcdea9f63f39be172c6
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/__init__.py
@@ -0,0 +1,2 @@
+from .conv import SparseConv3d, SparseInverseConv3d
+from . import config
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/config.py b/TRELLIS.2/trellis2/modules/sparse/conv/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac0848906703e7811300235e32d14e50ad5aac51
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/config.py
@@ -0,0 +1,3 @@
+SPCONV_ALGO = 'auto' # 'auto', 'implicit_gemm', 'native'
+FLEX_GEMM_ALGO = 'masked_implicit_gemm_splitk' # 'explicit_gemm', 'implicit_gemm', 'implicit_gemm_splitk', 'masked_implicit_gemm', 'masked_implicit_gemm_splitk'
+FLEX_GEMM_HASHMAP_RATIO = 2.0 # Ratio of hashmap size to input size
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/conv.py b/TRELLIS.2/trellis2/modules/sparse/conv/conv.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c7d40707a24e26ba2a11a90c41dbc9eb11e7ab2
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/conv.py
@@ -0,0 +1,30 @@
+from .. import config
+import importlib
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+
+
+_backends = {}
+
+
+class SparseConv3d(nn.Module):
+ def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding=None, bias=True, indice_key=None):
+ super(SparseConv3d, self).__init__()
+ if config.CONV not in _backends:
+ _backends[config.CONV] = importlib.import_module(f'..conv_{config.CONV}', __name__)
+ _backends[config.CONV].sparse_conv3d_init(self, in_channels, out_channels, kernel_size, stride, dilation, padding, bias, indice_key)
+
+ def forward(self, x: SparseTensor) -> SparseTensor:
+ return _backends[config.CONV].sparse_conv3d_forward(self, x)
+
+
+class SparseInverseConv3d(nn.Module):
+ def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None):
+ super(SparseInverseConv3d, self).__init__()
+ if config.CONV not in _backends:
+ _backends[config.CONV] = importlib.import_module(f'..conv_{config.CONV}', __name__)
+ _backends[config.CONV].sparse_inverse_conv3d_init(self, in_channels, out_channels, kernel_size, stride, dilation, bias, indice_key)
+
+ def forward(self, x: SparseTensor) -> SparseTensor:
+ return _backends[config.CONV].sparse_inverse_conv3d_forward(self, x)
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/conv_flex_gemm.py b/TRELLIS.2/trellis2/modules/sparse/conv/conv_flex_gemm.py
new file mode 100644
index 0000000000000000000000000000000000000000..d25619475e4bf39307f97d47b3828b19c48cd7da
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/conv_flex_gemm.py
@@ -0,0 +1,68 @@
+import math
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+from . import config
+import flex_gemm
+from flex_gemm.ops.spconv import sparse_submanifold_conv3d
+
+
+def sparse_conv3d_init(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding=None, bias=True, indice_key=None):
+ assert stride == 1 and (padding is None), 'Currently flex_gemm implementation only support submanifold sparse convolution (stride=1, padding=None)'
+
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+ self.kernel_size = tuple(kernel_size) if isinstance(kernel_size, (list, tuple)) else (kernel_size, ) * 3
+ self.stride = tuple(stride) if isinstance(stride, (list, tuple)) else (stride, ) * 3
+ self.dilation = tuple(dilation) if isinstance(dilation, (list, tuple)) else (dilation, ) * 3
+
+ self.weight = nn.Parameter(torch.empty((out_channels, in_channels, *self.kernel_size)))
+ if bias:
+ self.bias = nn.Parameter(torch.empty(out_channels))
+ else:
+ self.register_parameter("bias", None)
+
+ # initialize parameters
+ torch.nn.init.kaiming_uniform_(self.weight, a=math.sqrt(5))
+ if self.bias is not None:
+ fan_in, _ = torch.nn.init._calculate_fan_in_and_fan_out(self.weight)
+ if fan_in != 0:
+ bound = 1 / math.sqrt(fan_in)
+ torch.nn.init.uniform_(self.bias, -bound, bound)
+
+ # Permute weight (Co, Ci, Kd, Kh, Kw) -> (Co, Kd, Kh, Kw, Ci)
+ self.weight = nn.Parameter(self.weight.permute(0, 2, 3, 4, 1).contiguous())
+
+
+def sparse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ flex_gemm.ops.spconv.set_algorithm(config.FLEX_GEMM_ALGO)
+ flex_gemm.ops.spconv.set_hashmap_ratio(config.FLEX_GEMM_HASHMAP_RATIO)
+
+ # check if neighbor map is already computed
+ Co, Kd, Kh, Kw, Ci = self.weight.shape
+ neighbor_cache_key = f'SubMConv3d_neighbor_cache_{Kw}x{Kh}x{Kd}_dilation{self.dilation}'
+ neighbor_cache = x.get_spatial_cache(neighbor_cache_key)
+
+ out, neighbor_cache_ = sparse_submanifold_conv3d(
+ x.feats,
+ x.coords,
+ torch.Size([*x.shape, *x.spatial_shape]),
+ self.weight,
+ self.bias,
+ neighbor_cache,
+ self.dilation
+ )
+
+ if neighbor_cache is None:
+ x.register_spatial_cache(neighbor_cache_key, neighbor_cache_)
+
+ out = x.replace(out)
+ return out
+
+
+def sparse_inverse_conv3d_init(self, *args, **kwargs):
+ raise NotImplementedError('SparseInverseConv3d with flex_gemm is not implemented yet')
+
+
+def sparse_inverse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ raise NotImplementedError('SparseInverseConv3d with flex_gemm is not implemented yet')
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/conv_spconv.py b/TRELLIS.2/trellis2/modules/sparse/conv/conv_spconv.py
new file mode 100644
index 0000000000000000000000000000000000000000..f709708d4f8ee3bb98930c68b28e7f3b897fc591
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/conv_spconv.py
@@ -0,0 +1,73 @@
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+from . import config
+import spconv.pytorch as spconv
+
+
+def sparse_conv3d_init(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding=None, bias=True, indice_key=None):
+ algo = None
+ if config.SPCONV_ALGO == 'native':
+ algo = spconv.ConvAlgo.Native
+ elif config.SPCONV_ALGO == 'implicit_gemm':
+ algo = spconv.ConvAlgo.MaskImplicitGemm
+ if stride == 1 and (padding is None):
+ self.conv = spconv.SubMConv3d(in_channels, out_channels, kernel_size, dilation=dilation, bias=bias, indice_key=indice_key, algo=algo)
+ else:
+ self.conv = spconv.SparseConv3d(in_channels, out_channels, kernel_size, stride=stride, dilation=dilation, padding=padding, bias=bias, indice_key=indice_key, algo=algo)
+ self.stride = tuple(stride) if isinstance(stride, (list, tuple)) else (stride, stride, stride)
+ self.padding = padding
+
+
+def sparse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ spatial_changed = any(s != 1 for s in self.stride) or (self.padding is not None)
+ new_data = self.conv(x.data)
+ new_shape = [x.shape[0], self.conv.out_channels]
+ new_layout = None if spatial_changed else x.layout
+
+ if spatial_changed and (x.shape[0] != 1):
+ # spconv was non-1 stride will break the contiguous of the output tensor, sort by the coords
+ fwd = new_data.indices[:, 0].argsort()
+ bwd = torch.zeros_like(fwd).scatter_(0, fwd, torch.arange(fwd.shape[0], device=fwd.device))
+ sorted_feats = new_data.features[fwd]
+ sorted_coords = new_data.indices[fwd]
+ unsorted_data = new_data
+ new_data = spconv.SparseConvTensor(sorted_feats, sorted_coords, unsorted_data.spatial_shape, unsorted_data.batch_size) # type: ignore
+
+ out = SparseTensor(
+ new_data, shape=torch.Size(new_shape), layout=new_layout,
+ scale=tuple([s * stride for s, stride in zip(x._scale, self.stride)]),
+ spatial_cache=x._spatial_cache,
+ )
+
+ if spatial_changed and (x.shape[0] != 1):
+ out.register_spatial_cache(f'conv_{self.stride}_unsorted_data', unsorted_data)
+ out.register_spatial_cache(f'conv_{self.stride}_sort_bwd', bwd)
+
+ return out
+
+
+def sparse_inverse_conv3d_init(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None):
+ self.conv = spconv.SparseInverseConv3d(in_channels, out_channels, kernel_size, bias=bias, indice_key=indice_key)
+ self.stride = tuple(stride) if isinstance(stride, (list, tuple)) else (stride, stride, stride)
+
+
+def sparse_inverse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ spatial_changed = any(s != 1 for s in self.stride)
+ if spatial_changed:
+ # recover the original spconv order
+ data = x.get_spatial_cache(f'conv_{self.stride}_unsorted_data')
+ bwd = x.get_spatial_cache(f'conv_{self.stride}_sort_bwd')
+ data = data.replace_feature(x.feats[bwd])
+ else:
+ data = x.data
+
+ new_data = self.conv(data)
+ new_shape = [x.shape[0], self.conv.out_channels]
+ new_layout = None if spatial_changed else x.layout
+ out = SparseTensor(
+ new_data, shape=torch.Size(new_shape), layout=new_layout,
+ scale=tuple([s // stride for s, stride in zip(x._scale, self.stride)]),
+ spatial_cache=x._spatial_cache,
+ )
+ return out
diff --git a/TRELLIS.2/trellis2/modules/sparse/conv/conv_torchsparse.py b/TRELLIS.2/trellis2/modules/sparse/conv/conv_torchsparse.py
new file mode 100644
index 0000000000000000000000000000000000000000..5234bd15553aa8d71df280672475a898ffe56af7
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/conv/conv_torchsparse.py
@@ -0,0 +1,30 @@
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+import torchsparse
+
+
+def sparse_conv3d_init(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding=None, bias=True, indice_key=None):
+ self.conv = torchsparse.nn.Conv3d(in_channels, out_channels, kernel_size, stride, 0, dilation, bias)
+
+
+def sparse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ out = self.conv(x.data)
+ new_shape = [x.shape[0], self.conv.out_channels]
+ out = SparseTensor(out, shape=torch.Size(new_shape), layout=x.layout if all(s == 1 for s in self.conv.stride) else None)
+ out._spatial_cache = x._spatial_cache
+ out._scale = tuple([s * stride for s, stride in zip(x._scale, self.conv.stride)])
+ return out
+
+
+def sparse_inverse_conv3d_init(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None):
+ self.conv = torchsparse.nn.Conv3d(in_channels, out_channels, kernel_size, stride, 0, dilation, bias, transposed=True)
+
+
+def sparse_inverse_conv3d_forward(self, x: SparseTensor) -> SparseTensor:
+ out = self.conv(x.data)
+ new_shape = [x.shape[0], self.conv.out_channels]
+ out = SparseTensor(out, shape=torch.Size(new_shape), layout=x.layout if all(s == 1 for s in self.conv.stride) else None)
+ out._spatial_cache = x._spatial_cache
+ out._scale = tuple([s / stride for s, stride in zip(x._scale, self.conv.stride)])
+ return out
diff --git a/TRELLIS.2/trellis2/modules/sparse/linear.py b/TRELLIS.2/trellis2/modules/sparse/linear.py
new file mode 100644
index 0000000000000000000000000000000000000000..44317709ab16b17fa0132fd48e48519ea0ef9ea9
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/linear.py
@@ -0,0 +1,15 @@
+import torch
+import torch.nn as nn
+from . import VarLenTensor
+
+__all__ = [
+ 'SparseLinear'
+]
+
+
+class SparseLinear(nn.Linear):
+ def __init__(self, in_features, out_features, bias=True):
+ super(SparseLinear, self).__init__(in_features, out_features, bias)
+
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ return input.replace(super().forward(input.feats))
diff --git a/TRELLIS.2/trellis2/modules/sparse/nonlinearity.py b/TRELLIS.2/trellis2/modules/sparse/nonlinearity.py
new file mode 100644
index 0000000000000000000000000000000000000000..950e5c03c997905162e39fec701db49a2640700c
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/nonlinearity.py
@@ -0,0 +1,35 @@
+import torch
+import torch.nn as nn
+from . import VarLenTensor
+
+__all__ = [
+ 'SparseReLU',
+ 'SparseSiLU',
+ 'SparseGELU',
+ 'SparseActivation'
+]
+
+
+class SparseReLU(nn.ReLU):
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ return input.replace(super().forward(input.feats))
+
+
+class SparseSiLU(nn.SiLU):
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ return input.replace(super().forward(input.feats))
+
+
+class SparseGELU(nn.GELU):
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ return input.replace(super().forward(input.feats))
+
+
+class SparseActivation(nn.Module):
+ def __init__(self, activation: nn.Module):
+ super().__init__()
+ self.activation = activation
+
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ return input.replace(self.activation(input.feats))
+
diff --git a/TRELLIS.2/trellis2/modules/sparse/norm.py b/TRELLIS.2/trellis2/modules/sparse/norm.py
new file mode 100644
index 0000000000000000000000000000000000000000..95711203f0adbae1c7ea845e2500a3823997d652
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/norm.py
@@ -0,0 +1,64 @@
+import torch
+import torch.nn as nn
+from ..utils import manual_cast
+from . import VarLenTensor
+from . import config
+
+__all__ = [
+ 'SparseGroupNorm',
+ 'SparseLayerNorm',
+ 'SparseGroupNorm32',
+ 'SparseLayerNorm32',
+]
+
+
+class SparseGroupNorm(nn.GroupNorm):
+ def __init__(self, num_groups, num_channels, eps=1e-5, affine=True):
+ super(SparseGroupNorm, self).__init__(num_groups, num_channels, eps, affine)
+
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ nfeats = torch.zeros_like(input.feats)
+ for k in range(input.shape[0]):
+ bfeats = input.feats[input.layout[k]]
+ bfeats = bfeats.permute(1, 0).reshape(1, input.shape[1], -1)
+ bfeats = super().forward(bfeats)
+ bfeats = bfeats.reshape(input.shape[1], -1).permute(1, 0)
+ nfeats[input.layout[k]] = bfeats
+ return input.replace(nfeats)
+
+
+class SparseLayerNorm(nn.LayerNorm):
+ def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True):
+ super(SparseLayerNorm, self).__init__(normalized_shape, eps, elementwise_affine)
+
+ def forward(self, input: VarLenTensor) -> VarLenTensor:
+ nfeats = torch.zeros_like(input.feats)
+ for k in range(input.shape[0]):
+ bfeats = input.feats[input.layout[k]]
+ bfeats = bfeats.permute(1, 0).reshape(1, input.shape[1], -1)
+ bfeats = super().forward(bfeats)
+ bfeats = bfeats.reshape(input.shape[1], -1).permute(1, 0)
+ nfeats[input.layout[k]] = bfeats
+ return input.replace(nfeats)
+
+
+class SparseGroupNorm32(SparseGroupNorm):
+ """
+ A GroupNorm layer that converts to float32 before the forward pass.
+ """
+ def forward(self, x: VarLenTensor) -> VarLenTensor:
+ x_dtype = x.dtype
+ x = manual_cast(x, torch.float32)
+ o = super().forward(x)
+ return manual_cast(o, x_dtype)
+
+
+class SparseLayerNorm32(SparseLayerNorm):
+ """
+ A LayerNorm layer that converts to float32 before the forward pass.
+ """
+ def forward(self, x: VarLenTensor) -> VarLenTensor:
+ x_dtype = x.dtype
+ x = manual_cast(x, torch.float32)
+ o = super().forward(x)
+ return manual_cast(o, x_dtype)
diff --git a/TRELLIS.2/trellis2/modules/sparse/spatial/__init__.py b/TRELLIS.2/trellis2/modules/sparse/spatial/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e27425f165d271fd16a2c6f7b7684d4a81202ebd
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/spatial/__init__.py
@@ -0,0 +1,2 @@
+from .basic import *
+from .spatial2channel import *
diff --git a/TRELLIS.2/trellis2/modules/sparse/spatial/basic.py b/TRELLIS.2/trellis2/modules/sparse/spatial/basic.py
new file mode 100644
index 0000000000000000000000000000000000000000..eaeb8afefd889d8a94812c579383e528b8b56699
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/spatial/basic.py
@@ -0,0 +1,109 @@
+from typing import *
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+
+__all__ = [
+ 'SparseDownsample',
+ 'SparseUpsample',
+]
+
+
+class SparseDownsample(nn.Module):
+ """
+ Downsample a sparse tensor by a factor of `factor`.
+ Implemented as average pooling.
+ """
+ def __init__(self, factor: int, mode: Literal['mean', 'max'] = 'mean'):
+ super(SparseDownsample, self).__init__()
+ self.factor = factor
+ self.mode = mode
+ assert self.mode in ['mean', 'max'], f'Invalid mode: {self.mode}'
+
+ def forward(self, x: SparseTensor) -> SparseTensor:
+ cache = x.get_spatial_cache(f'downsample_{self.factor}')
+ if cache is None:
+ DIM = x.coords.shape[-1] - 1
+
+ coord = list(x.coords.unbind(dim=-1))
+ for i in range(DIM):
+ coord[i+1] = coord[i+1] // self.factor
+
+ MAX = [(s + self.factor - 1) // self.factor for s in x.spatial_shape]
+ OFFSET = torch.cumprod(torch.tensor(MAX[::-1]), 0).tolist()[::-1] + [1]
+ code = sum([c * o for c, o in zip(coord, OFFSET)])
+ code, idx = code.unique(return_inverse=True)
+
+ new_coords = torch.stack(
+ [code // OFFSET[0]] +
+ [(code // OFFSET[i+1]) % MAX[i] for i in range(DIM)],
+ dim=-1
+ )
+ else:
+ new_coords, idx = cache
+
+ new_feats = torch.scatter_reduce(
+ torch.zeros(new_coords.shape[0], x.feats.shape[1], device=x.feats.device, dtype=x.feats.dtype),
+ dim=0,
+ index=idx.unsqueeze(1).expand(-1, x.feats.shape[1]),
+ src=x.feats,
+ reduce=self.mode,
+ include_self=False,
+ )
+ out = SparseTensor(new_feats, new_coords, x._shape)
+ out._scale = tuple([s * self.factor for s in x._scale])
+ out._spatial_cache = x._spatial_cache
+
+ if cache is None:
+ x.register_spatial_cache(f'downsample_{self.factor}', (new_coords, idx))
+ out.register_spatial_cache(f'upsample_{self.factor}', (x.coords, idx))
+ out.register_spatial_cache(f'shape', torch.Size(MAX))
+ if self.training:
+ subidx = x.coords[:, 1:] % self.factor
+ subidx = sum([subidx[..., i] * self.factor ** i for i in range(DIM)])
+ subdivision = torch.zeros((new_coords.shape[0], self.factor ** DIM), device=x.device, dtype=torch.bool)
+ subdivision[idx, subidx] = True
+ out.register_spatial_cache(f'subdivision', subdivision)
+
+ return out
+
+
+class SparseUpsample(nn.Module):
+ """
+ Upsample a sparse tensor by a factor of `factor`.
+ Implemented as nearest neighbor interpolation.
+ """
+ def __init__(
+ self, factor: int
+ ):
+ super(SparseUpsample, self).__init__()
+ self.factor = factor
+
+ def forward(self, x: SparseTensor, subdivision: Optional[SparseTensor] = None) -> SparseTensor:
+ DIM = x.coords.shape[-1] - 1
+
+ cache = x.get_spatial_cache(f'upsample_{self.factor}')
+ if cache is None:
+ if subdivision is None:
+ raise ValueError('Cache not found. Provide subdivision tensor or pair SparseUpsample with SparseDownsample.')
+ else:
+ sub = subdivision.feats
+ N_leaf = sub.sum(dim=-1)
+ subidx = sub.nonzero()[:, -1]
+ new_coords = x.coords.clone().detach()
+ new_coords[:, 1:] *= self.factor
+ new_coords = torch.repeat_interleave(new_coords, N_leaf, dim=0, output_size=subidx.shape[0])
+ for i in range(DIM):
+ new_coords[:, i+1] += subidx // self.factor ** i % self.factor
+ idx = torch.repeat_interleave(torch.arange(x.coords.shape[0], device=x.device), N_leaf, dim=0, output_size=subidx.shape[0])
+ else:
+ new_coords, idx = cache
+
+ new_feats = x.feats[idx]
+ out = SparseTensor(new_feats, new_coords, x._shape)
+ out._scale = tuple([s / self.factor for s in x._scale])
+ if cache is not None: # only keep cache when subdiv following it
+ out._spatial_cache = x._spatial_cache
+
+ return out
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/sparse/spatial/spatial2channel.py b/TRELLIS.2/trellis2/modules/sparse/spatial/spatial2channel.py
new file mode 100644
index 0000000000000000000000000000000000000000..577f36d208726f64422f8774c3556a1d643f1e2d
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/spatial/spatial2channel.py
@@ -0,0 +1,93 @@
+from typing import *
+import torch
+import torch.nn as nn
+from .. import SparseTensor
+
+
+class SparseSpatial2Channel(nn.Module):
+ """
+ Downsample a sparse tensor by a factor of `factor`.
+ Implemented as rearranging its features from spatial to channel.
+ """
+ def __init__(self, factor: int = 2):
+ super(SparseSpatial2Channel, self).__init__()
+ self.factor = factor
+
+ def forward(self, x: SparseTensor) -> SparseTensor:
+ DIM = x.coords.shape[-1] - 1
+ cache = x.get_spatial_cache(f'spatial2channel_{self.factor}')
+ if cache is None:
+ coord = list(x.coords.unbind(dim=-1))
+ for i in range(DIM):
+ coord[i+1] = coord[i+1] // self.factor
+ subidx = x.coords[:, 1:] % self.factor
+ subidx = sum([subidx[..., i] * self.factor ** i for i in range(DIM)])
+
+ MAX = [(s + self.factor - 1) // self.factor for s in x.spatial_shape]
+ OFFSET = torch.cumprod(torch.tensor(MAX[::-1]), 0).tolist()[::-1] + [1]
+ code = sum([c * o for c, o in zip(coord, OFFSET)])
+ code, idx = code.unique(return_inverse=True)
+
+ new_coords = torch.stack(
+ [code // OFFSET[0]] +
+ [(code // OFFSET[i+1]) % MAX[i] for i in range(DIM)],
+ dim=-1
+ )
+ else:
+ new_coords, idx, subidx = cache
+
+ new_feats = torch.zeros(new_coords.shape[0] * self.factor ** DIM, x.feats.shape[1], device=x.feats.device, dtype=x.feats.dtype)
+ new_feats[idx * self.factor ** DIM + subidx] = x.feats
+
+ out = SparseTensor(new_feats.reshape(new_coords.shape[0], -1), new_coords, None if x._shape is None else torch.Size([x._shape[0], x._shape[1] * self.factor ** DIM]))
+ out._scale = tuple([s * self.factor for s in x._scale])
+ out._spatial_cache = x._spatial_cache
+
+ if cache is None:
+ x.register_spatial_cache(f'spatial2channel_{self.factor}', (new_coords, idx, subidx))
+ out.register_spatial_cache(f'channel2spatial_{self.factor}', (x.coords, idx, subidx))
+ out.register_spatial_cache(f'shape', torch.Size(MAX))
+ if self.training:
+ subdivision = torch.zeros((new_coords.shape[0], self.factor ** DIM), device=x.device, dtype=torch.bool)
+ subdivision[idx, subidx] = True
+ out.register_spatial_cache(f'subdivision', subdivision)
+
+ return out
+
+
+class SparseChannel2Spatial(nn.Module):
+ """
+ Upsample a sparse tensor by a factor of `factor`.
+ Implemented as rearranging its features from channel to spatial.
+ """
+ def __init__(self, factor: int = 2):
+ super(SparseChannel2Spatial, self).__init__()
+ self.factor = factor
+
+ def forward(self, x: SparseTensor, subdivision: Optional[SparseTensor] = None) -> SparseTensor:
+ DIM = x.coords.shape[-1] - 1
+
+ cache = x.get_spatial_cache(f'channel2spatial_{self.factor}')
+ if cache is None:
+ if subdivision is None:
+ raise ValueError('Cache not found. Provide subdivision tensor or pair SparseChannel2Spatial with SparseSpatial2Channel.')
+ else:
+ sub = subdivision.feats # [N, self.factor ** DIM]
+ N_leaf = sub.sum(dim=-1) # [N]
+ subidx = sub.nonzero()[:, -1]
+ new_coords = x.coords.clone().detach()
+ new_coords[:, 1:] *= self.factor
+ new_coords = torch.repeat_interleave(new_coords, N_leaf, dim=0, output_size=subidx.shape[0])
+ for i in range(DIM):
+ new_coords[:, i+1] += subidx // self.factor ** i % self.factor
+ idx = torch.repeat_interleave(torch.arange(x.coords.shape[0], device=x.device), N_leaf, dim=0, output_size=subidx.shape[0])
+ else:
+ new_coords, idx, subidx = cache
+
+ x_feats = x.feats.reshape(x.feats.shape[0] * self.factor ** DIM, -1)
+ new_feats = x_feats[idx * self.factor ** DIM + subidx]
+ out = SparseTensor(new_feats, new_coords, None if x._shape is None else torch.Size([x._shape[0], x._shape[1] // self.factor ** DIM]))
+ out._scale = tuple([s / self.factor for s in x._scale])
+ if cache is not None: # only keep cache when subdiv following it
+ out._spatial_cache = x._spatial_cache
+ return out
diff --git a/TRELLIS.2/trellis2/modules/sparse/transformer/__init__.py b/TRELLIS.2/trellis2/modules/sparse/transformer/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b08b0d4e5bc24060a2cdc8df75d06dce122972bd
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/transformer/__init__.py
@@ -0,0 +1,2 @@
+from .blocks import *
+from .modulated import *
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/sparse/transformer/blocks.py b/TRELLIS.2/trellis2/modules/sparse/transformer/blocks.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d1ec600404fba490894872109d44be6b6477186
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/transformer/blocks.py
@@ -0,0 +1,145 @@
+from typing import *
+import torch
+import torch.nn as nn
+from ..basic import VarLenTensor, SparseTensor
+from ..linear import SparseLinear
+from ..nonlinearity import SparseGELU
+from ..attention import SparseMultiHeadAttention
+from ...norm import LayerNorm32
+
+
+class SparseFeedForwardNet(nn.Module):
+ def __init__(self, channels: int, mlp_ratio: float = 4.0):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ SparseLinear(channels, int(channels * mlp_ratio)),
+ SparseGELU(approximate="tanh"),
+ SparseLinear(int(channels * mlp_ratio), channels),
+ )
+
+ def forward(self, x: VarLenTensor) -> VarLenTensor:
+ return self.mlp(x)
+
+
+class SparseTransformerBlock(nn.Module):
+ """
+ Sparse Transformer block (MSA + FFN).
+ """
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "swin"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qkv_bias: bool = True,
+ ln_affine: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.attn = SparseMultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.mlp = SparseFeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+
+ def _forward(self, x: SparseTensor) -> SparseTensor:
+ h = x.replace(self.norm1(x.feats))
+ h = self.attn(h)
+ x = x + h
+ h = x.replace(self.norm2(x.feats))
+ h = self.mlp(h)
+ x = x + h
+ return x
+
+ def forward(self, x: SparseTensor) -> SparseTensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, use_reentrant=False)
+ else:
+ return self._forward(x)
+
+
+class SparseTransformerCrossBlock(nn.Module):
+ """
+ Sparse Transformer cross-attention block (MSA + MCA + FFN).
+ """
+ def __init__(
+ self,
+ channels: int,
+ ctx_channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "swin"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ qk_rms_norm: bool = False,
+ qk_rms_norm_cross: bool = False,
+ qkv_bias: bool = True,
+ ln_affine: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.self_attn = SparseMultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ type="self",
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.cross_attn = SparseMultiHeadAttention(
+ channels,
+ ctx_channels=ctx_channels,
+ num_heads=num_heads,
+ type="cross",
+ attn_mode="full",
+ qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm_cross,
+ )
+ self.mlp = SparseFeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+
+ def _forward(self, x: SparseTensor, context: Union[torch.Tensor, VarLenTensor]) -> SparseTensor:
+ h = x.replace(self.norm1(x.feats))
+ h = self.self_attn(h)
+ x = x + h
+ h = x.replace(self.norm2(x.feats))
+ h = self.cross_attn(h, context)
+ x = x + h
+ h = x.replace(self.norm3(x.feats))
+ h = self.mlp(h)
+ x = x + h
+ return x
+
+ def forward(self, x: SparseTensor, context: Union[torch.Tensor, VarLenTensor]) -> SparseTensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, context, use_reentrant=False)
+ else:
+ return self._forward(x, context)
diff --git a/TRELLIS.2/trellis2/modules/sparse/transformer/modulated.py b/TRELLIS.2/trellis2/modules/sparse/transformer/modulated.py
new file mode 100644
index 0000000000000000000000000000000000000000..e616932ef7714f0ec8ae3add655411971978eb54
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/sparse/transformer/modulated.py
@@ -0,0 +1,166 @@
+from typing import *
+import torch
+import torch.nn as nn
+from ..basic import VarLenTensor, SparseTensor
+from ..attention import SparseMultiHeadAttention
+from ...norm import LayerNorm32
+from .blocks import SparseFeedForwardNet
+
+
+class ModulatedSparseTransformerBlock(nn.Module):
+ """
+ Sparse Transformer block (MSA + FFN) with adaptive layer norm conditioning.
+ """
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "swin"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[float, float] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qkv_bias: bool = True,
+ share_mod: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.share_mod = share_mod
+ self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.attn = SparseMultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.mlp = SparseFeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ nn.Linear(channels, 6 * channels, bias=True)
+ )
+ else:
+ self.modulation = nn.Parameter(torch.randn(6 * channels) / channels ** 0.5)
+
+ def _forward(self, x: SparseTensor, mod: torch.Tensor) -> SparseTensor:
+ if self.share_mod:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.modulation + mod).type(mod.dtype).chunk(6, dim=1)
+ else:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1)
+ h = x.replace(self.norm1(x.feats))
+ h = h * (1 + scale_msa) + shift_msa
+ h = self.attn(h)
+ h = h * gate_msa
+ x = x + h
+ h = x.replace(self.norm2(x.feats))
+ h = h * (1 + scale_mlp) + shift_mlp
+ h = self.mlp(h)
+ h = h * gate_mlp
+ x = x + h
+ return x
+
+ def forward(self, x: SparseTensor, mod: torch.Tensor) -> SparseTensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, mod, use_reentrant=False)
+ else:
+ return self._forward(x, mod)
+
+
+class ModulatedSparseTransformerCrossBlock(nn.Module):
+ """
+ Sparse Transformer cross-attention block (MSA + MCA + FFN) with adaptive layer norm conditioning.
+ """
+ def __init__(
+ self,
+ channels: int,
+ ctx_channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "swin"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[float, float] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qk_rms_norm_cross: bool = False,
+ qkv_bias: bool = True,
+ share_mod: bool = False,
+
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.share_mod = share_mod
+ self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6)
+ self.norm3 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.self_attn = SparseMultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ type="self",
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.cross_attn = SparseMultiHeadAttention(
+ channels,
+ ctx_channels=ctx_channels,
+ num_heads=num_heads,
+ type="cross",
+ attn_mode="full",
+ qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm_cross,
+ )
+ self.mlp = SparseFeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ nn.Linear(channels, 6 * channels, bias=True)
+ )
+ else:
+ self.modulation = nn.Parameter(torch.randn(6 * channels) / channels ** 0.5)
+
+ def _forward(self, x: SparseTensor, mod: torch.Tensor, context: Union[torch.Tensor, VarLenTensor]) -> SparseTensor:
+ if self.share_mod:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.modulation + mod).type(mod.dtype).chunk(6, dim=1)
+ else:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1)
+ h = x.replace(self.norm1(x.feats))
+ h = h * (1 + scale_msa) + shift_msa
+ h = self.self_attn(h)
+ h = h * gate_msa
+ x = x + h
+ h = x.replace(self.norm2(x.feats))
+ h = self.cross_attn(h, context)
+ x = x + h
+ h = x.replace(self.norm3(x.feats))
+ h = h * (1 + scale_mlp) + shift_mlp
+ h = self.mlp(h)
+ h = h * gate_mlp
+ x = x + h
+ return x
+
+ def forward(self, x: SparseTensor, mod: torch.Tensor, context: Union[torch.Tensor, VarLenTensor]) -> SparseTensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, mod, context, use_reentrant=False)
+ else:
+ return self._forward(x, mod, context)
diff --git a/TRELLIS.2/trellis2/modules/spatial.py b/TRELLIS.2/trellis2/modules/spatial.py
new file mode 100644
index 0000000000000000000000000000000000000000..79e268d36c2ba49b0275744022a1a1e19983dae3
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/spatial.py
@@ -0,0 +1,48 @@
+import torch
+
+
+def pixel_shuffle_3d(x: torch.Tensor, scale_factor: int) -> torch.Tensor:
+ """
+ 3D pixel shuffle.
+ """
+ B, C, H, W, D = x.shape
+ C_ = C // scale_factor**3
+ x = x.reshape(B, C_, scale_factor, scale_factor, scale_factor, H, W, D)
+ x = x.permute(0, 1, 5, 2, 6, 3, 7, 4)
+ x = x.reshape(B, C_, H*scale_factor, W*scale_factor, D*scale_factor)
+ return x
+
+
+def patchify(x: torch.Tensor, patch_size: int):
+ """
+ Patchify a tensor.
+
+ Args:
+ x (torch.Tensor): (N, C, *spatial) tensor
+ patch_size (int): Patch size
+ """
+ DIM = x.dim() - 2
+ for d in range(2, DIM + 2):
+ assert x.shape[d] % patch_size == 0, f"Dimension {d} of input tensor must be divisible by patch size, got {x.shape[d]} and {patch_size}"
+
+ x = x.reshape(*x.shape[:2], *sum([[x.shape[d] // patch_size, patch_size] for d in range(2, DIM + 2)], []))
+ x = x.permute(0, 1, *([2 * i + 3 for i in range(DIM)] + [2 * i + 2 for i in range(DIM)]))
+ x = x.reshape(x.shape[0], x.shape[1] * (patch_size ** DIM), *(x.shape[-DIM:]))
+ return x
+
+
+def unpatchify(x: torch.Tensor, patch_size: int):
+ """
+ Unpatchify a tensor.
+
+ Args:
+ x (torch.Tensor): (N, C, *spatial) tensor
+ patch_size (int): Patch size
+ """
+ DIM = x.dim() - 2
+ assert x.shape[1] % (patch_size ** DIM) == 0, f"Second dimension of input tensor must be divisible by patch size to unpatchify, got {x.shape[1]} and {patch_size ** DIM}"
+
+ x = x.reshape(x.shape[0], x.shape[1] // (patch_size ** DIM), *([patch_size] * DIM), *(x.shape[-DIM:]))
+ x = x.permute(0, 1, *(sum([[2 + DIM + i, 2 + i] for i in range(DIM)], [])))
+ x = x.reshape(x.shape[0], x.shape[1], *[x.shape[2 + 2 * i] * patch_size for i in range(DIM)])
+ return x
diff --git a/TRELLIS.2/trellis2/modules/transformer/__init__.py b/TRELLIS.2/trellis2/modules/transformer/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b08b0d4e5bc24060a2cdc8df75d06dce122972bd
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/transformer/__init__.py
@@ -0,0 +1,2 @@
+from .blocks import *
+from .modulated import *
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/transformer/blocks.py b/TRELLIS.2/trellis2/modules/transformer/blocks.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb6f5eb5462fec62aa5edc062104f643fca03bfa
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/transformer/blocks.py
@@ -0,0 +1,186 @@
+from typing import *
+import torch
+import torch.nn as nn
+from ..attention import MultiHeadAttention
+from ..norm import LayerNorm32
+
+
+class AbsolutePositionEmbedder(nn.Module):
+ """
+ Embeds spatial positions into vector representations.
+ """
+ def __init__(self, channels: int, in_channels: int = 3):
+ super().__init__()
+ self.channels = channels
+ self.in_channels = in_channels
+ self.freq_dim = channels // in_channels // 2
+ self.freqs = torch.arange(self.freq_dim, dtype=torch.float32) / self.freq_dim
+ self.freqs = 1.0 / (10000 ** self.freqs)
+
+ def _sin_cos_embedding(self, x: torch.Tensor) -> torch.Tensor:
+ """
+ Create sinusoidal position embeddings.
+
+ Args:
+ x: a 1-D Tensor of N indices
+
+ Returns:
+ an (N, D) Tensor of positional embeddings.
+ """
+ self.freqs = self.freqs.to(x.device)
+ out = torch.outer(x, self.freqs)
+ out = torch.cat([torch.sin(out), torch.cos(out)], dim=-1)
+ return out
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ """
+ Args:
+ x (torch.Tensor): (N, D) tensor of spatial positions
+ """
+ N, D = x.shape
+ assert D == self.in_channels, "Input dimension must match number of input channels"
+ embed = self._sin_cos_embedding(x.reshape(-1))
+ embed = embed.reshape(N, -1)
+ if embed.shape[1] < self.channels:
+ embed = torch.cat([embed, torch.zeros(N, self.channels - embed.shape[1], device=embed.device)], dim=-1)
+ return embed
+
+
+class FeedForwardNet(nn.Module):
+ def __init__(self, channels: int, mlp_ratio: float = 4.0):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ nn.Linear(channels, int(channels * mlp_ratio)),
+ nn.GELU(approximate="tanh"),
+ nn.Linear(int(channels * mlp_ratio), channels),
+ )
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return self.mlp(x)
+
+
+class TransformerBlock(nn.Module):
+ """
+ Transformer block (MSA + FFN).
+ """
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[int] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qkv_bias: bool = True,
+ ln_affine: bool = True,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.attn = MultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.mlp = FeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+
+ def _forward(self, x: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ h = self.norm1(x)
+ h = self.attn(h, phases=phases)
+ x = x + h
+ h = self.norm2(x)
+ h = self.mlp(h)
+ x = x + h
+ return x
+
+ def forward(self, x: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, phases, use_reentrant=False)
+ else:
+ return self._forward(x, phases)
+
+
+class TransformerCrossBlock(nn.Module):
+ """
+ Transformer cross-attention block (MSA + MCA + FFN).
+ """
+ def __init__(
+ self,
+ channels: int,
+ ctx_channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qk_rms_norm_cross: bool = False,
+ qkv_bias: bool = True,
+ ln_affine: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6)
+ self.self_attn = MultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ type="self",
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.cross_attn = MultiHeadAttention(
+ channels,
+ ctx_channels=ctx_channels,
+ num_heads=num_heads,
+ type="cross",
+ attn_mode="full",
+ qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm_cross,
+ )
+ self.mlp = FeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+
+ def _forward(self, x: torch.Tensor, context: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ h = self.norm1(x)
+ h = self.self_attn(h, phases=phases)
+ x = x + h
+ h = self.norm2(x)
+ h = self.cross_attn(h, context)
+ x = x + h
+ h = self.norm3(x)
+ h = self.mlp(h)
+ x = x + h
+ return x
+
+ def forward(self, x: torch.Tensor, context: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, context, phases, use_reentrant=False)
+ else:
+ return self._forward(x, context, phases)
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/transformer/modulated.py b/TRELLIS.2/trellis2/modules/transformer/modulated.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d71e584a4e137e88010023981271b2906efa30f
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/transformer/modulated.py
@@ -0,0 +1,165 @@
+from typing import *
+import torch
+import torch.nn as nn
+from ..attention import MultiHeadAttention
+from ..norm import LayerNorm32
+from .blocks import FeedForwardNet
+
+
+class ModulatedTransformerBlock(nn.Module):
+ """
+ Transformer block (MSA + FFN) with adaptive layer norm conditioning.
+ """
+ def __init__(
+ self,
+ channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qkv_bias: bool = True,
+ share_mod: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.share_mod = share_mod
+ self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.attn = MultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.mlp = FeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ nn.Linear(channels, 6 * channels, bias=True)
+ )
+ else:
+ self.modulation = nn.Parameter(torch.randn(6 * channels) / channels ** 0.5)
+
+ def _forward(self, x: torch.Tensor, mod: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.share_mod:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.modulation + mod).type(mod.dtype).chunk(6, dim=1)
+ else:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1)
+ h = self.norm1(x)
+ h = h * (1 + scale_msa.unsqueeze(1)) + shift_msa.unsqueeze(1)
+ h = self.attn(h, phases=phases)
+ h = h * gate_msa.unsqueeze(1)
+ x = x + h
+ h = self.norm2(x)
+ h = h * (1 + scale_mlp.unsqueeze(1)) + shift_mlp.unsqueeze(1)
+ h = self.mlp(h)
+ h = h * gate_mlp.unsqueeze(1)
+ x = x + h
+ return x
+
+ def forward(self, x: torch.Tensor, mod: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, mod, phases, use_reentrant=False)
+ else:
+ return self._forward(x, mod, phases)
+
+
+class ModulatedTransformerCrossBlock(nn.Module):
+ """
+ Transformer cross-attention block (MSA + MCA + FFN) with adaptive layer norm conditioning.
+ """
+ def __init__(
+ self,
+ channels: int,
+ ctx_channels: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: Literal["full", "windowed"] = "full",
+ window_size: Optional[int] = None,
+ shift_window: Optional[Tuple[int, int, int]] = None,
+ use_checkpoint: bool = False,
+ use_rope: bool = False,
+ rope_freq: Tuple[int, int] = (1.0, 10000.0),
+ qk_rms_norm: bool = False,
+ qk_rms_norm_cross: bool = False,
+ qkv_bias: bool = True,
+ share_mod: bool = False,
+ ):
+ super().__init__()
+ self.use_checkpoint = use_checkpoint
+ self.share_mod = share_mod
+ self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6)
+ self.norm3 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6)
+ self.self_attn = MultiHeadAttention(
+ channels,
+ num_heads=num_heads,
+ type="self",
+ attn_mode=attn_mode,
+ window_size=window_size,
+ shift_window=shift_window,
+ qkv_bias=qkv_bias,
+ use_rope=use_rope,
+ rope_freq=rope_freq,
+ qk_rms_norm=qk_rms_norm,
+ )
+ self.cross_attn = MultiHeadAttention(
+ channels,
+ ctx_channels=ctx_channels,
+ num_heads=num_heads,
+ type="cross",
+ attn_mode="full",
+ qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm_cross,
+ )
+ self.mlp = FeedForwardNet(
+ channels,
+ mlp_ratio=mlp_ratio,
+ )
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ nn.Linear(channels, 6 * channels, bias=True)
+ )
+ else:
+ self.modulation = nn.Parameter(torch.randn(6 * channels) / channels ** 0.5)
+
+ def _forward(self, x: torch.Tensor, mod: torch.Tensor, context: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.share_mod:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.modulation + mod).type(mod.dtype).chunk(6, dim=1)
+ else:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1)
+ h = self.norm1(x)
+ h = h * (1 + scale_msa.unsqueeze(1)) + shift_msa.unsqueeze(1)
+ h = self.self_attn(h, phases=phases)
+ h = h * gate_msa.unsqueeze(1)
+ x = x + h
+ h = self.norm2(x)
+ h = self.cross_attn(h, context)
+ x = x + h
+ h = self.norm3(x)
+ h = h * (1 + scale_mlp.unsqueeze(1)) + shift_mlp.unsqueeze(1)
+ h = self.mlp(h)
+ h = h * gate_mlp.unsqueeze(1)
+ x = x + h
+ return x
+
+ def forward(self, x: torch.Tensor, mod: torch.Tensor, context: torch.Tensor, phases: Optional[torch.Tensor] = None) -> torch.Tensor:
+ if self.use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(self._forward, x, mod, context, phases, use_reentrant=False)
+ else:
+ return self._forward(x, mod, context, phases)
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/modules/utils.py b/TRELLIS.2/trellis2/modules/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d92d7d5b0ab07972fb6e0397c9c8e525e196211
--- /dev/null
+++ b/TRELLIS.2/trellis2/modules/utils.py
@@ -0,0 +1,87 @@
+import torch
+import torch.nn as nn
+from ..modules import sparse as sp
+
+MIX_PRECISION_MODULES = (
+ nn.Conv1d,
+ nn.Conv2d,
+ nn.Conv3d,
+ nn.ConvTranspose1d,
+ nn.ConvTranspose2d,
+ nn.ConvTranspose3d,
+ nn.Linear,
+ sp.SparseConv3d,
+ sp.SparseInverseConv3d,
+ sp.SparseLinear,
+)
+
+
+def convert_module_to_f16(l):
+ """
+ Convert primitive modules to float16.
+ """
+ if isinstance(l, MIX_PRECISION_MODULES):
+ for p in l.parameters():
+ p.data = p.data.half()
+
+
+def convert_module_to_f32(l):
+ """
+ Convert primitive modules to float32, undoing convert_module_to_f16().
+ """
+ if isinstance(l, MIX_PRECISION_MODULES):
+ for p in l.parameters():
+ p.data = p.data.float()
+
+
+def convert_module_to(l, dtype):
+ """
+ Convert primitive modules to the given dtype.
+ """
+ if isinstance(l, MIX_PRECISION_MODULES):
+ for p in l.parameters():
+ p.data = p.data.to(dtype)
+
+
+def zero_module(module):
+ """
+ Zero out the parameters of a module and return it.
+ """
+ for p in module.parameters():
+ p.detach().zero_()
+ return module
+
+
+def scale_module(module, scale):
+ """
+ Scale the parameters of a module and return it.
+ """
+ for p in module.parameters():
+ p.detach().mul_(scale)
+ return module
+
+
+def modulate(x, shift, scale):
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+
+def manual_cast(tensor, dtype):
+ """
+ Cast if autocast is not enabled.
+ """
+ if not torch.is_autocast_enabled():
+ return tensor.type(dtype)
+ return tensor
+
+
+def str_to_dtype(dtype_str: str):
+ return {
+ 'f16': torch.float16,
+ 'fp16': torch.float16,
+ 'float16': torch.float16,
+ 'bf16': torch.bfloat16,
+ 'bfloat16': torch.bfloat16,
+ 'f32': torch.float32,
+ 'fp32': torch.float32,
+ 'float32': torch.float32,
+ }[dtype_str]
diff --git a/TRELLIS.2/trellis2/pipelines/__init__.py b/TRELLIS.2/trellis2/pipelines/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..53d8917ecad2d7c814a62447587ff31936a9c339
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/__init__.py
@@ -0,0 +1,55 @@
+import importlib
+
+__attributes = {
+ "Trellis2ImageTo3DPipeline": "trellis2_image_to_3d",
+ "Trellis2ImageTo3DCascadePipeline": "trellis2_image_to_3d_cascade",
+ "Trellis2ImageToTexturePipeline": "trellis2_image_to_tex",
+}
+
+__submodules = ['samplers', 'rembg']
+
+__all__ = list(__attributes.keys()) + __submodules
+
+def __getattr__(name):
+ if name not in globals():
+ if name in __attributes:
+ module_name = __attributes[name]
+ module = importlib.import_module(f".{module_name}", __name__)
+ globals()[name] = getattr(module, name)
+ elif name in __submodules:
+ module = importlib.import_module(f".{name}", __name__)
+ globals()[name] = module
+ else:
+ raise AttributeError(f"module {__name__} has no attribute {name}")
+ return globals()[name]
+
+
+def from_pretrained(path: str):
+ """
+ Load a pipeline from a model folder or a Hugging Face model hub.
+
+ Args:
+ path: The path to the model. Can be either local path or a Hugging Face model name.
+ """
+ import os
+ import json
+ is_local = os.path.exists(f"{path}/pipeline.json")
+
+ if is_local:
+ config_file = f"{path}/pipeline.json"
+ else:
+ from huggingface_hub import hf_hub_download
+ config_file = hf_hub_download(path, "pipeline.json")
+
+ with open(config_file, 'r') as f:
+ config = json.load(f)
+ return globals()[config['name']].from_pretrained(path)
+
+
+# For PyLance
+if __name__ == '__main__':
+ from . import samplers, rembg
+ from .trellis_image_to_3d import TrellisImageTo3DPipeline
+ from .trellis2_image_to_3d import Trellis2ImageTo3DPipeline
+ from .trellis2_image_to_3d_cascade import Trellis2ImageTo3DCascadePipeline
+ from .trellis2_image_to_tex import Trellis2ImageToTexturePipeline
diff --git a/TRELLIS.2/trellis2/pipelines/base.py b/TRELLIS.2/trellis2/pipelines/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..d897825c5f4f64dbbdca54c6a1af9001e8b8f56b
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/base.py
@@ -0,0 +1,70 @@
+from typing import *
+import torch
+import torch.nn as nn
+from .. import models
+
+
+class Pipeline:
+ """
+ A base class for pipelines.
+ """
+ def __init__(
+ self,
+ models: dict[str, nn.Module] = None,
+ ):
+ if models is None:
+ return
+ self.models = models
+ for model in self.models.values():
+ model.eval()
+
+ @staticmethod
+ def from_pretrained(path: str) -> "Pipeline":
+ """
+ Load a pretrained model.
+ """
+ import os
+ import json
+ is_local = os.path.exists(f"{path}/pipeline.json")
+
+ if is_local:
+ config_file = f"{path}/pipeline.json"
+ else:
+ from huggingface_hub import hf_hub_download
+ config_file = hf_hub_download(path, "pipeline.json")
+
+ with open(config_file, 'r') as f:
+ args = json.load(f)['args']
+
+ _models = {}
+ for k, v in args['models'].items():
+ try:
+ _models[k] = models.from_pretrained(f"{path}/{v}")
+ except Exception as e:
+ _models[k] = models.from_pretrained(v)
+
+ new_pipeline = Pipeline(_models)
+ new_pipeline._pretrained_args = args
+ return new_pipeline
+
+ @property
+ def device(self) -> torch.device:
+ if hasattr(self, '_device'):
+ return self._device
+ for model in self.models.values():
+ if hasattr(model, 'device'):
+ return model.device
+ for model in self.models.values():
+ if hasattr(model, 'parameters'):
+ return next(model.parameters()).device
+ raise RuntimeError("No device found.")
+
+ def to(self, device: torch.device) -> None:
+ for model in self.models.values():
+ model.to(device)
+
+ def cuda(self) -> None:
+ self.to(torch.device("cuda"))
+
+ def cpu(self) -> None:
+ self.to(torch.device("cpu"))
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/pipelines/rembg/BiRefNet.py b/TRELLIS.2/trellis2/pipelines/rembg/BiRefNet.py
new file mode 100644
index 0000000000000000000000000000000000000000..c71a99274823aefe6f18ab921a5beb074177de18
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/rembg/BiRefNet.py
@@ -0,0 +1,42 @@
+from typing import *
+from transformers import AutoModelForImageSegmentation
+import torch
+from torchvision import transforms
+from PIL import Image
+
+
+class BiRefNet:
+ def __init__(self, model_name: str = "ZhengPeng7/BiRefNet"):
+ self.model = AutoModelForImageSegmentation.from_pretrained(
+ model_name, trust_remote_code=True
+ )
+ self.model.eval()
+ self.transform_image = transforms.Compose(
+ [
+ transforms.Resize((1024, 1024)),
+ transforms.ToTensor(),
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
+ ]
+ )
+
+ def to(self, device: str):
+ self.model.to(device)
+
+ def cuda(self):
+ self.model.cuda()
+
+ def cpu(self):
+ self.model.cpu()
+
+ def __call__(self, image: Image.Image) -> Image.Image:
+ image_size = image.size
+ input_images = self.transform_image(image).unsqueeze(0).to("cuda")
+ # Prediction
+ with torch.no_grad():
+ preds = self.model(input_images)[-1].sigmoid().cpu()
+ pred = preds[0].squeeze()
+ pred_pil = transforms.ToPILImage()(pred)
+ mask = pred_pil.resize(image_size)
+ image.putalpha(mask)
+ return image
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/pipelines/rembg/__init__.py b/TRELLIS.2/trellis2/pipelines/rembg/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc1eed1ba0c962478fc48132432f2e649fe03411
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/rembg/__init__.py
@@ -0,0 +1 @@
+from .BiRefNet import *
diff --git a/TRELLIS.2/trellis2/pipelines/samplers/__init__.py b/TRELLIS.2/trellis2/pipelines/samplers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a69b95e5963c6d3a837518ed9c3cf6972235d60
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/samplers/__init__.py
@@ -0,0 +1,6 @@
+from .base import Sampler
+from .flow_euler import (
+ FlowEulerSampler,
+ FlowEulerCfgSampler,
+ FlowEulerGuidanceIntervalSampler,
+)
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/pipelines/samplers/base.py b/TRELLIS.2/trellis2/pipelines/samplers/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..1966ce787009a5ee0c1ed06dce491525ff1dbcbf
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/samplers/base.py
@@ -0,0 +1,20 @@
+from typing import *
+from abc import ABC, abstractmethod
+
+
+class Sampler(ABC):
+ """
+ A base class for samplers.
+ """
+
+ @abstractmethod
+ def sample(
+ self,
+ model,
+ **kwargs
+ ):
+ """
+ Sample from a model.
+ """
+ pass
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/pipelines/samplers/classifier_free_guidance_mixin.py b/TRELLIS.2/trellis2/pipelines/samplers/classifier_free_guidance_mixin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c7a4da4c1324bed5319f89916b532a159471d84
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/samplers/classifier_free_guidance_mixin.py
@@ -0,0 +1,29 @@
+from typing import *
+
+
+class ClassifierFreeGuidanceSamplerMixin:
+ """
+ A mixin class for samplers that apply classifier-free guidance.
+ """
+
+ def _inference_model(self, model, x_t, t, cond, neg_cond, guidance_strength, guidance_rescale=0.0, **kwargs):
+ if guidance_strength == 1:
+ return super()._inference_model(model, x_t, t, cond, **kwargs)
+ elif guidance_strength == 0:
+ return super()._inference_model(model, x_t, t, neg_cond, **kwargs)
+ else:
+ pred_pos = super()._inference_model(model, x_t, t, cond, **kwargs)
+ pred_neg = super()._inference_model(model, x_t, t, neg_cond, **kwargs)
+ pred = guidance_strength * pred_pos + (1 - guidance_strength) * pred_neg
+
+ # CFG rescale
+ if guidance_rescale > 0:
+ x_0_pos = self._pred_to_xstart(x_t, t, pred_pos)
+ x_0_cfg = self._pred_to_xstart(x_t, t, pred)
+ std_pos = x_0_pos.std(dim=list(range(1, x_0_pos.ndim)), keepdim=True)
+ std_cfg = x_0_cfg.std(dim=list(range(1, x_0_cfg.ndim)), keepdim=True)
+ x_0_rescaled = x_0_cfg * (std_pos / std_cfg)
+ x_0 = guidance_rescale * x_0_rescaled + (1 - guidance_rescale) * x_0_cfg
+ pred = self._xstart_to_pred(x_t, t, x_0)
+
+ return pred
diff --git a/TRELLIS.2/trellis2/pipelines/samplers/flow_euler.py b/TRELLIS.2/trellis2/pipelines/samplers/flow_euler.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ff72b84221f210f6cb06684bdf13aedc6cf20c3
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/samplers/flow_euler.py
@@ -0,0 +1,208 @@
+from typing import *
+import torch
+import numpy as np
+from tqdm import tqdm
+from easydict import EasyDict as edict
+from .base import Sampler
+from .classifier_free_guidance_mixin import ClassifierFreeGuidanceSamplerMixin
+from .guidance_interval_mixin import GuidanceIntervalSamplerMixin
+
+
+class FlowEulerSampler(Sampler):
+ """
+ Generate samples from a flow-matching model using Euler sampling.
+
+ Args:
+ sigma_min: The minimum scale of noise in flow.
+ """
+ def __init__(
+ self,
+ sigma_min: float,
+ ):
+ self.sigma_min = sigma_min
+
+ def _eps_to_xstart(self, x_t, t, eps):
+ assert x_t.shape == eps.shape
+ return (x_t - (self.sigma_min + (1 - self.sigma_min) * t) * eps) / (1 - t)
+
+ def _xstart_to_eps(self, x_t, t, x_0):
+ assert x_t.shape == x_0.shape
+ return (x_t - (1 - t) * x_0) / (self.sigma_min + (1 - self.sigma_min) * t)
+
+ def _v_to_xstart_eps(self, x_t, t, v):
+ assert x_t.shape == v.shape
+ eps = (1 - t) * v + x_t
+ x_0 = (1 - self.sigma_min) * x_t - (self.sigma_min + (1 - self.sigma_min) * t) * v
+ return x_0, eps
+
+ def _pred_to_xstart(self, x_t, t, pred):
+ return (1 - self.sigma_min) * x_t - (self.sigma_min + (1 - self.sigma_min) * t) * pred
+
+ def _xstart_to_pred(self, x_t, t, x_0):
+ return ((1 - self.sigma_min) * x_t - x_0) / (self.sigma_min + (1 - self.sigma_min) * t)
+
+ def _inference_model(self, model, x_t, t, cond=None, **kwargs):
+ t = torch.tensor([1000 * t] * x_t.shape[0], device=x_t.device, dtype=torch.float32)
+ return model(x_t, t, cond, **kwargs)
+
+ def _get_model_prediction(self, model, x_t, t, cond=None, **kwargs):
+ pred_v = self._inference_model(model, x_t, t, cond, **kwargs)
+ pred_x_0, pred_eps = self._v_to_xstart_eps(x_t=x_t, t=t, v=pred_v)
+ return pred_x_0, pred_eps, pred_v
+
+ @torch.no_grad()
+ def sample_once(
+ self,
+ model,
+ x_t,
+ t: float,
+ t_prev: float,
+ cond: Optional[Any] = None,
+ **kwargs
+ ):
+ """
+ Sample x_{t-1} from the model using Euler method.
+
+ Args:
+ model: The model to sample from.
+ x_t: The [N x C x ...] tensor of noisy inputs at time t.
+ t: The current timestep.
+ t_prev: The previous timestep.
+ cond: conditional information.
+ **kwargs: Additional arguments for model inference.
+
+ Returns:
+ a dict containing the following
+ - 'pred_x_prev': x_{t-1}.
+ - 'pred_x_0': a prediction of x_0.
+ """
+ pred_x_0, pred_eps, pred_v = self._get_model_prediction(model, x_t, t, cond, **kwargs)
+ pred_x_prev = x_t - (t - t_prev) * pred_v
+ return edict({"pred_x_prev": pred_x_prev, "pred_x_0": pred_x_0})
+
+ @torch.no_grad()
+ def sample(
+ self,
+ model,
+ noise,
+ cond: Optional[Any] = None,
+ steps: int = 50,
+ rescale_t: float = 1.0,
+ verbose: bool = True,
+ tqdm_desc: str = "Sampling",
+ **kwargs
+ ):
+ """
+ Generate samples from the model using Euler method.
+
+ Args:
+ model: The model to sample from.
+ noise: The initial noise tensor.
+ cond: conditional information.
+ steps: The number of steps to sample.
+ rescale_t: The rescale factor for t.
+ verbose: If True, show a progress bar.
+ tqdm_desc: A customized tqdm desc.
+ **kwargs: Additional arguments for model_inference.
+
+ Returns:
+ a dict containing the following
+ - 'samples': the model samples.
+ - 'pred_x_t': a list of prediction of x_t.
+ - 'pred_x_0': a list of prediction of x_0.
+ """
+ sample = noise
+ t_seq = np.linspace(1, 0, steps + 1)
+ t_seq = rescale_t * t_seq / (1 + (rescale_t - 1) * t_seq)
+ t_seq = t_seq.tolist()
+ t_pairs = list((t_seq[i], t_seq[i + 1]) for i in range(steps))
+ ret = edict({"samples": None, "pred_x_t": [], "pred_x_0": []})
+ for t, t_prev in tqdm(t_pairs, desc=tqdm_desc, disable=not verbose):
+ out = self.sample_once(model, sample, t, t_prev, cond, **kwargs)
+ sample = out.pred_x_prev
+ ret.pred_x_t.append(out.pred_x_prev)
+ ret.pred_x_0.append(out.pred_x_0)
+ ret.samples = sample
+ return ret
+
+
+class FlowEulerCfgSampler(ClassifierFreeGuidanceSamplerMixin, FlowEulerSampler):
+ """
+ Generate samples from a flow-matching model using Euler sampling with classifier-free guidance.
+ """
+ @torch.no_grad()
+ def sample(
+ self,
+ model,
+ noise,
+ cond,
+ neg_cond,
+ steps: int = 50,
+ rescale_t: float = 1.0,
+ guidance_strength: float = 3.0,
+ verbose: bool = True,
+ **kwargs
+ ):
+ """
+ Generate samples from the model using Euler method.
+
+ Args:
+ model: The model to sample from.
+ noise: The initial noise tensor.
+ cond: conditional information.
+ neg_cond: negative conditional information.
+ steps: The number of steps to sample.
+ rescale_t: The rescale factor for t.
+ guidance_strength: The strength of classifier-free guidance.
+ verbose: If True, show a progress bar.
+ **kwargs: Additional arguments for model_inference.
+
+ Returns:
+ a dict containing the following
+ - 'samples': the model samples.
+ - 'pred_x_t': a list of prediction of x_t.
+ - 'pred_x_0': a list of prediction of x_0.
+ """
+ return super().sample(model, noise, cond, steps, rescale_t, verbose, neg_cond=neg_cond, guidance_strength=guidance_strength, **kwargs)
+
+
+class FlowEulerGuidanceIntervalSampler(GuidanceIntervalSamplerMixin, ClassifierFreeGuidanceSamplerMixin, FlowEulerSampler):
+ """
+ Generate samples from a flow-matching model using Euler sampling with classifier-free guidance and interval.
+ """
+ @torch.no_grad()
+ def sample(
+ self,
+ model,
+ noise,
+ cond,
+ neg_cond,
+ steps: int = 50,
+ rescale_t: float = 1.0,
+ guidance_strength: float = 3.0,
+ guidance_interval: Tuple[float, float] = (0.0, 1.0),
+ verbose: bool = True,
+ **kwargs
+ ):
+ """
+ Generate samples from the model using Euler method.
+
+ Args:
+ model: The model to sample from.
+ noise: The initial noise tensor.
+ cond: conditional information.
+ neg_cond: negative conditional information.
+ steps: The number of steps to sample.
+ rescale_t: The rescale factor for t.
+ guidance_strength: The strength of classifier-free guidance.
+ guidance_interval: The interval for classifier-free guidance.
+ verbose: If True, show a progress bar.
+ **kwargs: Additional arguments for model_inference.
+
+ Returns:
+ a dict containing the following
+ - 'samples': the model samples.
+ - 'pred_x_t': a list of prediction of x_t.
+ - 'pred_x_0': a list of prediction of x_0.
+ """
+ return super().sample(model, noise, cond, steps, rescale_t, verbose, neg_cond=neg_cond, guidance_strength=guidance_strength, guidance_interval=guidance_interval, **kwargs)
diff --git a/TRELLIS.2/trellis2/pipelines/samplers/guidance_interval_mixin.py b/TRELLIS.2/trellis2/pipelines/samplers/guidance_interval_mixin.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f57869a17d1626f5b2c58eb3c477127bf464abf
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/samplers/guidance_interval_mixin.py
@@ -0,0 +1,13 @@
+from typing import *
+
+
+class GuidanceIntervalSamplerMixin:
+ """
+ A mixin class for samplers that apply classifier-free guidance with interval.
+ """
+
+ def _inference_model(self, model, x_t, t, cond, guidance_strength, guidance_interval, **kwargs):
+ if guidance_interval[0] <= t <= guidance_interval[1]:
+ return super()._inference_model(model, x_t, t, cond, guidance_strength=guidance_strength, **kwargs)
+ else:
+ return super()._inference_model(model, x_t, t, cond, guidance_strength=1, **kwargs)
diff --git a/TRELLIS.2/trellis2/pipelines/trellis2_image_to_3d.py b/TRELLIS.2/trellis2/pipelines/trellis2_image_to_3d.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d7afd59cff2daaf2060c10a050dd1506bf6bebe
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/trellis2_image_to_3d.py
@@ -0,0 +1,588 @@
+from typing import *
+import torch
+import torch.nn as nn
+import numpy as np
+from PIL import Image
+from .base import Pipeline
+from . import samplers, rembg
+from ..modules.sparse import SparseTensor
+from ..modules import image_feature_extractor
+from ..representations import Mesh, MeshWithVoxel
+
+
+class Trellis2ImageTo3DPipeline(Pipeline):
+ """
+ Pipeline for inferring Trellis2 image-to-3D models.
+
+ Args:
+ models (dict[str, nn.Module]): The models to use in the pipeline.
+ sparse_structure_sampler (samplers.Sampler): The sampler for the sparse structure.
+ shape_slat_sampler (samplers.Sampler): The sampler for the structured latent.
+ tex_slat_sampler (samplers.Sampler): The sampler for the texture latent.
+ sparse_structure_sampler_params (dict): The parameters for the sparse structure sampler.
+ shape_slat_sampler_params (dict): The parameters for the structured latent sampler.
+ tex_slat_sampler_params (dict): The parameters for the texture latent sampler.
+ shape_slat_normalization (dict): The normalization parameters for the structured latent.
+ tex_slat_normalization (dict): The normalization parameters for the texture latent.
+ image_cond_model (Callable): The image conditioning model.
+ rembg_model (Callable): The model for removing background.
+ low_vram (bool): Whether to use low-VRAM mode.
+ """
+ def __init__(
+ self,
+ models: dict[str, nn.Module] = None,
+ sparse_structure_sampler: samplers.Sampler = None,
+ shape_slat_sampler: samplers.Sampler = None,
+ tex_slat_sampler: samplers.Sampler = None,
+ sparse_structure_sampler_params: dict = None,
+ shape_slat_sampler_params: dict = None,
+ tex_slat_sampler_params: dict = None,
+ shape_slat_normalization: dict = None,
+ tex_slat_normalization: dict = None,
+ image_cond_model: Callable = None,
+ rembg_model: Callable = None,
+ low_vram: bool = True,
+ default_pipeline_type: str = '1024_cascade',
+ ):
+ if models is None:
+ return
+ super().__init__(models)
+ self.sparse_structure_sampler = sparse_structure_sampler
+ self.shape_slat_sampler = shape_slat_sampler
+ self.tex_slat_sampler = tex_slat_sampler
+ self.sparse_structure_sampler_params = sparse_structure_sampler_params
+ self.shape_slat_sampler_params = shape_slat_sampler_params
+ self.tex_slat_sampler_params = tex_slat_sampler_params
+ self.shape_slat_normalization = shape_slat_normalization
+ self.tex_slat_normalization = tex_slat_normalization
+ self.image_cond_model = image_cond_model
+ self.rembg_model = rembg_model
+ self.low_vram = low_vram
+ self.default_pipeline_type = default_pipeline_type
+ self.pbr_attr_layout = {
+ 'base_color': slice(0, 3),
+ 'metallic': slice(3, 4),
+ 'roughness': slice(4, 5),
+ 'alpha': slice(5, 6),
+ }
+ self._device = 'cpu'
+
+ @staticmethod
+ def from_pretrained(path: str) -> "Trellis2ImageTo3DPipeline":
+ """
+ Load a pretrained model.
+
+ Args:
+ path (str): The path to the model. Can be either local path or a Hugging Face repository.
+ """
+ pipeline = super(Trellis2ImageTo3DPipeline, Trellis2ImageTo3DPipeline).from_pretrained(path)
+ new_pipeline = Trellis2ImageTo3DPipeline()
+ new_pipeline.__dict__ = pipeline.__dict__
+ args = pipeline._pretrained_args
+
+ new_pipeline.sparse_structure_sampler = getattr(samplers, args['sparse_structure_sampler']['name'])(**args['sparse_structure_sampler']['args'])
+ new_pipeline.sparse_structure_sampler_params = args['sparse_structure_sampler']['params']
+
+ new_pipeline.shape_slat_sampler = getattr(samplers, args['shape_slat_sampler']['name'])(**args['shape_slat_sampler']['args'])
+ new_pipeline.shape_slat_sampler_params = args['shape_slat_sampler']['params']
+
+ new_pipeline.tex_slat_sampler = getattr(samplers, args['tex_slat_sampler']['name'])(**args['tex_slat_sampler']['args'])
+ new_pipeline.tex_slat_sampler_params = args['tex_slat_sampler']['params']
+
+ new_pipeline.shape_slat_normalization = args['shape_slat_normalization']
+ new_pipeline.tex_slat_normalization = args['tex_slat_normalization']
+
+ new_pipeline.image_cond_model = getattr(image_feature_extractor, args['image_cond_model']['name'])(**args['image_cond_model']['args'])
+ new_pipeline.rembg_model = getattr(rembg, args['rembg_model']['name'])(**args['rembg_model']['args'])
+
+ new_pipeline.low_vram = args.get('low_vram', True)
+ new_pipeline.default_pipeline_type = args.get('default_pipeline_type', '1024_cascade')
+ new_pipeline.pbr_attr_layout = {
+ 'base_color': slice(0, 3),
+ 'metallic': slice(3, 4),
+ 'roughness': slice(4, 5),
+ 'alpha': slice(5, 6),
+ }
+ new_pipeline._device = 'cpu'
+
+ return new_pipeline
+
+ def to(self, device: torch.device) -> None:
+ self._device = device
+ if not self.low_vram:
+ super().to(device)
+ self.image_cond_model.to(device)
+ if self.rembg_model is not None:
+ self.rembg_model.to(device)
+
+ def preprocess_image(self, input: Image.Image) -> Image.Image:
+ """
+ Preprocess the input image.
+ """
+ # if has alpha channel, use it directly; otherwise, remove background
+ has_alpha = False
+ if input.mode == 'RGBA':
+ alpha = np.array(input)[:, :, 3]
+ if not np.all(alpha == 255):
+ has_alpha = True
+ max_size = max(input.size)
+ scale = min(1, 1024 / max_size)
+ if scale < 1:
+ input = input.resize((int(input.width * scale), int(input.height * scale)), Image.Resampling.LANCZOS)
+ if has_alpha:
+ output = input
+ else:
+ input = input.convert('RGB')
+ if self.low_vram:
+ self.rembg_model.to(self.device)
+ output = self.rembg_model(input)
+ if self.low_vram:
+ self.rembg_model.cpu()
+ output_np = np.array(output)
+ alpha = output_np[:, :, 3]
+ bbox = np.argwhere(alpha > 0.8 * 255)
+ bbox = np.min(bbox[:, 1]), np.min(bbox[:, 0]), np.max(bbox[:, 1]), np.max(bbox[:, 0])
+ center = (bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2
+ size = max(bbox[2] - bbox[0], bbox[3] - bbox[1])
+ size = int(size * 1)
+ bbox = center[0] - size // 2, center[1] - size // 2, center[0] + size // 2, center[1] + size // 2
+ output = output.crop(bbox) # type: ignore
+ output = np.array(output).astype(np.float32) / 255
+ output = output[:, :, :3] * output[:, :, 3:4]
+ output = Image.fromarray((output * 255).astype(np.uint8))
+ return output
+
+ def get_cond(self, image: Union[torch.Tensor, list[Image.Image]], resolution: int, include_neg_cond: bool = True) -> dict:
+ """
+ Get the conditioning information for the model.
+
+ Args:
+ image (Union[torch.Tensor, list[Image.Image]]): The image prompts.
+
+ Returns:
+ dict: The conditioning information
+ """
+ self.image_cond_model.image_size = resolution
+ if self.low_vram:
+ self.image_cond_model.to(self.device)
+ cond = self.image_cond_model(image)
+ if self.low_vram:
+ self.image_cond_model.cpu()
+ if not include_neg_cond:
+ return {'cond': cond}
+ neg_cond = torch.zeros_like(cond)
+ return {
+ 'cond': cond,
+ 'neg_cond': neg_cond,
+ }
+
+ def sample_sparse_structure(
+ self,
+ cond: dict,
+ resolution: int,
+ num_samples: int = 1,
+ sampler_params: dict = {},
+ ) -> torch.Tensor:
+ """
+ Sample sparse structures with the given conditioning.
+
+ Args:
+ cond (dict): The conditioning information.
+ resolution (int): The resolution of the sparse structure.
+ num_samples (int): The number of samples to generate.
+ sampler_params (dict): Additional parameters for the sampler.
+ """
+ # Sample sparse structure latent
+ flow_model = self.models['sparse_structure_flow_model']
+ reso = flow_model.resolution
+ in_channels = flow_model.in_channels
+ noise = torch.randn(num_samples, in_channels, reso, reso, reso).to(self.device)
+ sampler_params = {**self.sparse_structure_sampler_params, **sampler_params}
+ if self.low_vram:
+ flow_model.to(self.device)
+ z_s = self.sparse_structure_sampler.sample(
+ flow_model,
+ noise,
+ **cond,
+ **sampler_params,
+ verbose=True,
+ tqdm_desc="Sampling sparse structure",
+ ).samples
+ if self.low_vram:
+ flow_model.cpu()
+
+ # Decode sparse structure latent
+ decoder = self.models['sparse_structure_decoder']
+ if self.low_vram:
+ decoder.to(self.device)
+ decoded = decoder(z_s)>0
+ if self.low_vram:
+ decoder.cpu()
+ if resolution != decoded.shape[2]:
+ ratio = decoded.shape[2] // resolution
+ decoded = torch.nn.functional.max_pool3d(decoded.float(), ratio, ratio, 0) > 0.5
+ coords = torch.argwhere(decoded)[:, [0, 2, 3, 4]].int()
+
+ return coords
+
+ def sample_shape_slat(
+ self,
+ cond: dict,
+ flow_model,
+ coords: torch.Tensor,
+ sampler_params: dict = {},
+ ) -> SparseTensor:
+ """
+ Sample structured latent with the given conditioning.
+
+ Args:
+ cond (dict): The conditioning information.
+ coords (torch.Tensor): The coordinates of the sparse structure.
+ sampler_params (dict): Additional parameters for the sampler.
+ """
+ # Sample structured latent
+ noise = SparseTensor(
+ feats=torch.randn(coords.shape[0], flow_model.in_channels).to(self.device),
+ coords=coords,
+ )
+ sampler_params = {**self.shape_slat_sampler_params, **sampler_params}
+ if self.low_vram:
+ flow_model.to(self.device)
+ slat = self.shape_slat_sampler.sample(
+ flow_model,
+ noise,
+ **cond,
+ **sampler_params,
+ verbose=True,
+ tqdm_desc="Sampling shape SLat",
+ ).samples
+ if self.low_vram:
+ flow_model.cpu()
+
+ std = torch.tensor(self.shape_slat_normalization['std'])[None].to(slat.device)
+ mean = torch.tensor(self.shape_slat_normalization['mean'])[None].to(slat.device)
+ slat = slat * std + mean
+
+ return slat
+
+ def sample_shape_slat_cascade(
+ self,
+ lr_cond: dict,
+ cond: dict,
+ flow_model_lr,
+ flow_model,
+ lr_resolution: int,
+ resolution: int,
+ coords: torch.Tensor,
+ sampler_params: dict = {},
+ max_num_tokens: int = 49152,
+ ) -> SparseTensor:
+ """
+ Sample structured latent with the given conditioning.
+
+ Args:
+ cond (dict): The conditioning information.
+ coords (torch.Tensor): The coordinates of the sparse structure.
+ sampler_params (dict): Additional parameters for the sampler.
+ """
+ # LR
+ noise = SparseTensor(
+ feats=torch.randn(coords.shape[0], flow_model_lr.in_channels).to(self.device),
+ coords=coords,
+ )
+ sampler_params = {**self.shape_slat_sampler_params, **sampler_params}
+ if self.low_vram:
+ flow_model_lr.to(self.device)
+ slat = self.shape_slat_sampler.sample(
+ flow_model_lr,
+ noise,
+ **lr_cond,
+ **sampler_params,
+ verbose=True,
+ tqdm_desc="Sampling shape SLat",
+ ).samples
+ if self.low_vram:
+ flow_model_lr.cpu()
+ std = torch.tensor(self.shape_slat_normalization['std'])[None].to(slat.device)
+ mean = torch.tensor(self.shape_slat_normalization['mean'])[None].to(slat.device)
+ slat = slat * std + mean
+
+ # Upsample
+ if self.low_vram:
+ self.models['shape_slat_decoder'].to(self.device)
+ self.models['shape_slat_decoder'].low_vram = True
+ hr_coords = self.models['shape_slat_decoder'].upsample(slat, upsample_times=4)
+ if self.low_vram:
+ self.models['shape_slat_decoder'].cpu()
+ self.models['shape_slat_decoder'].low_vram = False
+ hr_resolution = resolution
+ while True:
+ quant_coords = torch.cat([
+ hr_coords[:, :1],
+ ((hr_coords[:, 1:] + 0.5) / lr_resolution * (hr_resolution // 16)).int(),
+ ], dim=1)
+ coords = quant_coords.unique(dim=0)
+ num_tokens = coords.shape[0]
+ if num_tokens < max_num_tokens or hr_resolution == 1024:
+ if hr_resolution != resolution:
+ print(f"Due to the limited number of tokens, the resolution is reduced to {hr_resolution}.")
+ break
+ hr_resolution -= 128
+
+ # Sample structured latent
+ noise = SparseTensor(
+ feats=torch.randn(coords.shape[0], flow_model.in_channels).to(self.device),
+ coords=coords,
+ )
+ sampler_params = {**self.shape_slat_sampler_params, **sampler_params}
+ if self.low_vram:
+ flow_model.to(self.device)
+ slat = self.shape_slat_sampler.sample(
+ flow_model,
+ noise,
+ **cond,
+ **sampler_params,
+ verbose=True,
+ tqdm_desc="Sampling shape SLat",
+ ).samples
+ if self.low_vram:
+ flow_model.cpu()
+
+ std = torch.tensor(self.shape_slat_normalization['std'])[None].to(slat.device)
+ mean = torch.tensor(self.shape_slat_normalization['mean'])[None].to(slat.device)
+ slat = slat * std + mean
+
+ return slat, hr_resolution
+
+ def decode_shape_slat(
+ self,
+ slat: SparseTensor,
+ resolution: int,
+ ) -> Tuple[List[Mesh], List[SparseTensor]]:
+ """
+ Decode the structured latent.
+
+ Args:
+ slat (SparseTensor): The structured latent.
+ formats (List[str]): The formats to decode the structured latent to.
+
+ Returns:
+ List[Mesh]: The decoded meshes.
+ List[SparseTensor]: The decoded substructures.
+ """
+ self.models['shape_slat_decoder'].set_resolution(resolution)
+ if self.low_vram:
+ self.models['shape_slat_decoder'].to(self.device)
+ self.models['shape_slat_decoder'].low_vram = True
+ ret = self.models['shape_slat_decoder'](slat, return_subs=True)
+ if self.low_vram:
+ self.models['shape_slat_decoder'].cpu()
+ self.models['shape_slat_decoder'].low_vram = False
+ return ret
+
+ def sample_tex_slat(
+ self,
+ cond: dict,
+ flow_model,
+ shape_slat: SparseTensor,
+ sampler_params: dict = {},
+ ) -> SparseTensor:
+ """
+ Sample structured latent with the given conditioning.
+
+ Args:
+ cond (dict): The conditioning information.
+ shape_slat (SparseTensor): The structured latent for shape
+ sampler_params (dict): Additional parameters for the sampler.
+ """
+ # Sample structured latent
+ std = torch.tensor(self.shape_slat_normalization['std'])[None].to(shape_slat.device)
+ mean = torch.tensor(self.shape_slat_normalization['mean'])[None].to(shape_slat.device)
+ shape_slat = (shape_slat - mean) / std
+
+ in_channels = flow_model.in_channels if isinstance(flow_model, nn.Module) else flow_model[0].in_channels
+ noise = shape_slat.replace(feats=torch.randn(shape_slat.coords.shape[0], in_channels - shape_slat.feats.shape[1]).to(self.device))
+ sampler_params = {**self.tex_slat_sampler_params, **sampler_params}
+ if self.low_vram:
+ flow_model.to(self.device)
+ slat = self.tex_slat_sampler.sample(
+ flow_model,
+ noise,
+ concat_cond=shape_slat,
+ **cond,
+ **sampler_params,
+ verbose=True,
+ tqdm_desc="Sampling texture SLat",
+ ).samples
+ if self.low_vram:
+ flow_model.cpu()
+
+ std = torch.tensor(self.tex_slat_normalization['std'])[None].to(slat.device)
+ mean = torch.tensor(self.tex_slat_normalization['mean'])[None].to(slat.device)
+ slat = slat * std + mean
+
+ return slat
+
+ def decode_tex_slat(
+ self,
+ slat: SparseTensor,
+ subs: List[SparseTensor],
+ ) -> SparseTensor:
+ """
+ Decode the structured latent.
+
+ Args:
+ slat (SparseTensor): The structured latent.
+ formats (List[str]): The formats to decode the structured latent to.
+
+ Returns:
+ List[SparseTensor]: The decoded texture voxels
+ """
+ if self.low_vram:
+ self.models['tex_slat_decoder'].to(self.device)
+ ret = self.models['tex_slat_decoder'](slat, guide_subs=subs) * 0.5 + 0.5
+ if self.low_vram:
+ self.models['tex_slat_decoder'].cpu()
+ return ret
+
+ @torch.no_grad()
+ def decode_latent(
+ self,
+ shape_slat: SparseTensor,
+ tex_slat: SparseTensor,
+ resolution: int,
+ ) -> List[MeshWithVoxel]:
+ """
+ Decode the latent codes.
+
+ Args:
+ shape_slat (SparseTensor): The structured latent for shape.
+ tex_slat (SparseTensor): The structured latent for texture.
+ resolution (int): The resolution of the output.
+ """
+ meshes, subs = self.decode_shape_slat(shape_slat, resolution)
+ tex_voxels = self.decode_tex_slat(tex_slat, subs)
+ out_mesh = []
+ for m, v in zip(meshes, tex_voxels):
+ m.fill_holes()
+ out_mesh.append(
+ MeshWithVoxel(
+ m.vertices, m.faces,
+ origin = [-0.5, -0.5, -0.5],
+ voxel_size = 1 / resolution,
+ coords = v.coords[:, 1:],
+ attrs = v.feats,
+ voxel_shape = torch.Size([*v.shape, *v.spatial_shape]),
+ layout=self.pbr_attr_layout
+ )
+ )
+ return out_mesh
+
+ @torch.no_grad()
+ def run(
+ self,
+ image: Image.Image,
+ num_samples: int = 1,
+ seed: int = 42,
+ sparse_structure_sampler_params: dict = {},
+ shape_slat_sampler_params: dict = {},
+ tex_slat_sampler_params: dict = {},
+ preprocess_image: bool = True,
+ return_latent: bool = False,
+ pipeline_type: Optional[str] = None,
+ max_num_tokens: int = 49152,
+ ) -> List[MeshWithVoxel]:
+ """
+ Run the pipeline.
+
+ Args:
+ image (Image.Image): The image prompt.
+ num_samples (int): The number of samples to generate.
+ seed (int): The random seed.
+ sparse_structure_sampler_params (dict): Additional parameters for the sparse structure sampler.
+ shape_slat_sampler_params (dict): Additional parameters for the shape SLat sampler.
+ tex_slat_sampler_params (dict): Additional parameters for the texture SLat sampler.
+ preprocess_image (bool): Whether to preprocess the image.
+ return_latent (bool): Whether to return the latent codes.
+ pipeline_type (str): The type of the pipeline. Options: '512', '1024', '1024_cascade', '1536_cascade'.
+ max_num_tokens (int): The maximum number of tokens to use.
+ """
+ # Check pipeline type
+ pipeline_type = pipeline_type or self.default_pipeline_type
+ if pipeline_type == '512':
+ assert 'shape_slat_flow_model_512' in self.models, "No 512 resolution shape SLat flow model found."
+ assert 'tex_slat_flow_model_512' in self.models, "No 512 resolution texture SLat flow model found."
+ elif pipeline_type == '1024':
+ assert 'shape_slat_flow_model_1024' in self.models, "No 1024 resolution shape SLat flow model found."
+ assert 'tex_slat_flow_model_1024' in self.models, "No 1024 resolution texture SLat flow model found."
+ elif pipeline_type == '1024_cascade':
+ assert 'shape_slat_flow_model_512' in self.models, "No 512 resolution shape SLat flow model found."
+ assert 'shape_slat_flow_model_1024' in self.models, "No 1024 resolution shape SLat flow model found."
+ assert 'tex_slat_flow_model_1024' in self.models, "No 1024 resolution texture SLat flow model found."
+ elif pipeline_type == '1536_cascade':
+ assert 'shape_slat_flow_model_512' in self.models, "No 512 resolution shape SLat flow model found."
+ assert 'shape_slat_flow_model_1024' in self.models, "No 1024 resolution shape SLat flow model found."
+ assert 'tex_slat_flow_model_1024' in self.models, "No 1024 resolution texture SLat flow model found."
+ else:
+ raise ValueError(f"Invalid pipeline type: {pipeline_type}")
+
+ if preprocess_image:
+ image = self.preprocess_image(image)
+ torch.manual_seed(seed)
+ cond_512 = self.get_cond([image], 512)
+ cond_1024 = self.get_cond([image], 1024) if pipeline_type != '512' else None
+ ss_res = {'512': 32, '1024': 64, '1024_cascade': 32, '1536_cascade': 32}[pipeline_type]
+ coords = self.sample_sparse_structure(
+ cond_512, ss_res,
+ num_samples, sparse_structure_sampler_params
+ )
+ if pipeline_type == '512':
+ shape_slat = self.sample_shape_slat(
+ cond_512, self.models['shape_slat_flow_model_512'],
+ coords, shape_slat_sampler_params
+ )
+ tex_slat = self.sample_tex_slat(
+ cond_512, self.models['tex_slat_flow_model_512'],
+ shape_slat, tex_slat_sampler_params
+ )
+ res = 512
+ elif pipeline_type == '1024':
+ shape_slat = self.sample_shape_slat(
+ cond_1024, self.models['shape_slat_flow_model_1024'],
+ coords, shape_slat_sampler_params
+ )
+ tex_slat = self.sample_tex_slat(
+ cond_1024, self.models['tex_slat_flow_model_1024'],
+ shape_slat, tex_slat_sampler_params
+ )
+ res = 1024
+ elif pipeline_type == '1024_cascade':
+ shape_slat, res = self.sample_shape_slat_cascade(
+ cond_512, cond_1024,
+ self.models['shape_slat_flow_model_512'], self.models['shape_slat_flow_model_1024'],
+ 512, 1024,
+ coords, shape_slat_sampler_params,
+ max_num_tokens
+ )
+ tex_slat = self.sample_tex_slat(
+ cond_1024, self.models['tex_slat_flow_model_1024'],
+ shape_slat, tex_slat_sampler_params
+ )
+ elif pipeline_type == '1536_cascade':
+ shape_slat, res = self.sample_shape_slat_cascade(
+ cond_512, cond_1024,
+ self.models['shape_slat_flow_model_512'], self.models['shape_slat_flow_model_1024'],
+ 512, 1536,
+ coords, shape_slat_sampler_params,
+ max_num_tokens
+ )
+ tex_slat = self.sample_tex_slat(
+ cond_1024, self.models['tex_slat_flow_model_1024'],
+ shape_slat, tex_slat_sampler_params
+ )
+ torch.cuda.empty_cache()
+ out_mesh = self.decode_latent(shape_slat, tex_slat, res)
+ if return_latent:
+ return out_mesh, (shape_slat, tex_slat, res)
+ else:
+ return out_mesh
diff --git a/TRELLIS.2/trellis2/pipelines/trellis2_image_to_tex.py b/TRELLIS.2/trellis2/pipelines/trellis2_image_to_tex.py
new file mode 100755
index 0000000000000000000000000000000000000000..ab8b777656e87ff93cd55febcd797584adab26f0
--- /dev/null
+++ b/TRELLIS.2/trellis2/pipelines/trellis2_image_to_tex.py
@@ -0,0 +1,271 @@
+from typing import *
+import numpy as np
+import torch
+from .. import _C
+from flex_gemm.kernels import cuda as flexgemm_kernels
+
+__all__ = [
+ "mesh_to_flexible_dual_grid",
+ "flexible_dual_grid_to_mesh",
+]
+
+@torch.no_grad()
+def mesh_to_flexible_dual_grid(
+ vertices: torch.Tensor,
+ faces: torch.Tensor,
+ voxel_size: Union[float, list, tuple, np.ndarray, torch.Tensor] = None,
+ grid_size: Union[int, list, tuple, np.ndarray, torch.Tensor] = None,
+ aabb: Union[list, tuple, np.ndarray, torch.Tensor] = None,
+ face_weight: float = 1.0,
+ boundary_weight: float = 1.0,
+ regularization_weight: float = 0.1,
+ timing: bool = False,
+) -> Union[torch.Tensor, torch.Tensor, torch.Tensor]:
+ """
+ Voxelize a mesh into a sparse voxel grid.
+
+ Args:
+ vertices (torch.Tensor): The vertices of the mesh.
+ faces (torch.Tensor): The faces of the mesh.
+ voxel_size (float, list, tuple, np.ndarray, torch.Tensor): The size of each voxel.
+ grid_size (int, list, tuple, np.ndarray, torch.Tensor): The size of the grid.
+ NOTE: One of voxel_size and grid_size must be provided.
+ aabb (list, tuple, np.ndarray, torch.Tensor): The axis-aligned bounding box of the mesh.
+ If not provided, it will be computed automatically.
+ face_weight (float): The weight of the face term in the dual contouring algorithm.
+ boundary_weight (float): The weight of the boundary term in the dual contouring algorithm.
+ regularization_weight (float): The weight of the regularization term in the dual contouring algorithm.
+ timing (bool): Whether to time the voxelization process.
+
+ Returns:
+ torch.Tensor: The indices of the voxels that are occupied by the mesh.
+ The shape of the tensor is (N, 3), where N is the number of occupied voxels.
+ torch.Tensor: The dual vertices of the mesh.
+ torch.Tensor: The intersected flag of each voxel.
+ """
+
+ # Load mesh
+ vertices = vertices.float()
+ faces = faces.int()
+
+ # Voxelize settings
+ assert voxel_size is not None or grid_size is not None, "Either voxel_size or grid_size must be provided"
+
+ if voxel_size is not None:
+ if isinstance(voxel_size, float):
+ voxel_size = [voxel_size, voxel_size, voxel_size]
+ if isinstance(voxel_size, (list, tuple)):
+ voxel_size = np.array(voxel_size)
+ if isinstance(voxel_size, np.ndarray):
+ voxel_size = torch.tensor(voxel_size, dtype=torch.float32)
+ assert isinstance(voxel_size, torch.Tensor), f"voxel_size must be a float, list, tuple, np.ndarray, or torch.Tensor, but got {type(voxel_size)}"
+ assert voxel_size.dim() == 1, f"voxel_size must be a 1D tensor, but got {voxel_size.shape}"
+ assert voxel_size.size(0) == 3, f"voxel_size must have 3 elements, but got {voxel_size.size(0)}"
+
+ if grid_size is not None:
+ if isinstance(grid_size, int):
+ grid_size = [grid_size, grid_size, grid_size]
+ if isinstance(grid_size, (list, tuple)):
+ grid_size = np.array(grid_size)
+ if isinstance(grid_size, np.ndarray):
+ grid_size = torch.tensor(grid_size, dtype=torch.int32)
+ assert isinstance(grid_size, torch.Tensor), f"grid_size must be an int, list, tuple, np.ndarray, or torch.Tensor, but got {type(grid_size)}"
+ assert grid_size.dim() == 1, f"grid_size must be a 1D tensor, but got {grid_size.shape}"
+ assert grid_size.size(0) == 3, f"grid_size must have 3 elements, but got {grid_size.size(0)}"
+
+ if aabb is not None:
+ if isinstance(aabb, (list, tuple)):
+ aabb = np.array(aabb)
+ if isinstance(aabb, np.ndarray):
+ aabb = torch.tensor(aabb, dtype=torch.float32)
+ assert isinstance(aabb, torch.Tensor), f"aabb must be a list, tuple, np.ndarray, or torch.Tensor, but got {type(aabb)}"
+ assert aabb.dim() == 2, f"aabb must be a 2D tensor, but got {aabb.shape}"
+ assert aabb.size(0) == 2, f"aabb must have 2 rows, but got {aabb.size(0)}"
+ assert aabb.size(1) == 3, f"aabb must have 3 columns, but got {aabb.size(1)}"
+
+ # Auto adjust aabb
+ if aabb is None:
+ min_xyz = vertices.min(dim=0).values
+ max_xyz = vertices.max(dim=0).values
+
+ if voxel_size is not None:
+ padding = torch.ceil((max_xyz - min_xyz) / voxel_size) * voxel_size - (max_xyz - min_xyz)
+ min_xyz -= padding * 0.5
+ max_xyz += padding * 0.5
+ if grid_size is not None:
+ padding = (max_xyz - min_xyz) / (grid_size - 1)
+ min_xyz -= padding * 0.5
+ max_xyz += padding * 0.5
+
+ aabb = torch.stack([min_xyz, max_xyz], dim=0).float().cuda()
+
+ # Fill voxel size or grid size
+ if voxel_size is None:
+ voxel_size = (aabb[1] - aabb[0]) / grid_size
+ if grid_size is None:
+ grid_size = ((aabb[1] - aabb[0]) / voxel_size).round().int()
+
+ # subdivide mesh
+ vertices = vertices - aabb[0].reshape(1, 3)
+ grid_range = torch.stack([torch.zeros_like(grid_size), grid_size], dim=0).int()
+
+ ret = _C.mesh_to_flexible_dual_grid_cpu(
+ vertices,
+ faces,
+ voxel_size,
+ grid_range,
+ face_weight,
+ boundary_weight,
+ regularization_weight,
+ timing,
+ )
+
+ return ret
+
+
+def flexible_dual_grid_to_mesh(
+ coords: torch.Tensor,
+ dual_vertices: torch.Tensor,
+ intersected_flag: torch.Tensor,
+ split_weight: Union[torch.Tensor, None],
+ aabb: Union[list, tuple, np.ndarray, torch.Tensor],
+ voxel_size: Union[float, list, tuple, np.ndarray, torch.Tensor] = None,
+ grid_size: Union[int, list, tuple, np.ndarray, torch.Tensor] = None,
+ train: bool = False,
+):
+ """
+ Extract mesh from sparse voxel structures using flexible dual grid.
+
+ Args:
+ coords (torch.Tensor): The coordinates of the voxels.
+ dual_vertices (torch.Tensor): The dual vertices.
+ intersected_flag (torch.Tensor): The intersected flag.
+ split_weight (torch.Tensor): The split weight of each dual quad. If None, the algorithm
+ will split based on minimum angle.
+ aabb (list, tuple, np.ndarray, torch.Tensor): The axis-aligned bounding box of the mesh.
+ voxel_size (float, list, tuple, np.ndarray, torch.Tensor): The size of each voxel.
+ grid_size (int, list, tuple, np.ndarray, torch.Tensor): The size of the grid.
+ NOTE: One of voxel_size and grid_size must be provided.
+ train (bool): Whether to use training mode.
+
+ Returns:
+ vertices (torch.Tensor): The vertices of the mesh.
+ faces (torch.Tensor): The faces of the mesh.
+ """
+ # Static variables
+ if not hasattr(flexible_dual_grid_to_mesh, "edge_neighbor_voxel_offset"):
+ flexible_dual_grid_to_mesh.edge_neighbor_voxel_offset = torch.tensor([
+ [[0, 0, 0], [0, 0, 1], [0, 1, 1], [0, 1, 0]], # x-axis
+ [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]], # y-axis
+ [[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]], # z-axis
+ ], dtype=torch.int, device=coords.device).unsqueeze(0)
+ if not hasattr(flexible_dual_grid_to_mesh, "quad_split_1"):
+ flexible_dual_grid_to_mesh.quad_split_1 = torch.tensor([0, 1, 2, 0, 2, 3], dtype=torch.long, device=coords.device, requires_grad=False)
+ if not hasattr(flexible_dual_grid_to_mesh, "quad_split_2"):
+ flexible_dual_grid_to_mesh.quad_split_2 = torch.tensor([0, 1, 3, 3, 1, 2], dtype=torch.long, device=coords.device, requires_grad=False)
+ if not hasattr(flexible_dual_grid_to_mesh, "quad_split_train"):
+ flexible_dual_grid_to_mesh.quad_split_train = torch.tensor([0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4], dtype=torch.long, device=coords.device, requires_grad=False)
+
+ # AABB
+ if isinstance(aabb, (list, tuple)):
+ aabb = np.array(aabb)
+ if isinstance(aabb, np.ndarray):
+ aabb = torch.tensor(aabb, dtype=torch.float32, device=coords.device)
+ assert isinstance(aabb, torch.Tensor), f"aabb must be a list, tuple, np.ndarray, or torch.Tensor, but got {type(aabb)}"
+ assert aabb.dim() == 2, f"aabb must be a 2D tensor, but got {aabb.shape}"
+ assert aabb.size(0) == 2, f"aabb must have 2 rows, but got {aabb.size(0)}"
+ assert aabb.size(1) == 3, f"aabb must have 3 columns, but got {aabb.size(1)}"
+
+ # Voxel size
+ if voxel_size is not None:
+ if isinstance(voxel_size, float):
+ voxel_size = [voxel_size, voxel_size, voxel_size]
+ if isinstance(voxel_size, (list, tuple)):
+ voxel_size = np.array(voxel_size)
+ if isinstance(voxel_size, np.ndarray):
+ voxel_size = torch.tensor(voxel_size, dtype=torch.float32, device=coords.device)
+ grid_size = ((aabb[1] - aabb[0]) / voxel_size).round().int()
+ else:
+ assert grid_size is not None, "Either voxel_size or grid_size must be provided"
+ if isinstance(grid_size, int):
+ grid_size = [grid_size, grid_size, grid_size]
+ if isinstance(grid_size, (list, tuple)):
+ grid_size = np.array(grid_size)
+ if isinstance(grid_size, np.ndarray):
+ grid_size = torch.tensor(grid_size, dtype=torch.int32, device=coords.device)
+ voxel_size = (aabb[1] - aabb[0]) / grid_size
+ assert isinstance(voxel_size, torch.Tensor), f"voxel_size must be a float, list, tuple, np.ndarray, or torch.Tensor, but got {type(voxel_size)}"
+ assert voxel_size.dim() == 1, f"voxel_size must be a 1D tensor, but got {voxel_size.shape}"
+ assert voxel_size.size(0) == 3, f"voxel_size must have 3 elements, but got {voxel_size.size(0)}"
+ assert isinstance(grid_size, torch.Tensor), f"grid_size must be an int, list, tuple, np.ndarray, or torch.Tensor, but got {type(grid_size)}"
+ assert grid_size.dim() == 1, f"grid_size must be a 1D tensor, but got {grid_size.shape}"
+ assert grid_size.size(0) == 3, f"grid_size must have 3 elements, but got {grid_size.size(0)}"
+
+ # Extract mesh
+ N = dual_vertices.shape[0]
+ mesh_vertices = (coords.float() + dual_vertices) / (2 * N) - 0.5
+
+ # Store active voxels into hashmap
+ hashmap = torch.full((2 * int(2 * N),), 0xffffffff, dtype=torch.uint32, device=coords.device)
+ flexgemm_kernels.hashmap_insert_3d_idx_as_val_cuda(hashmap, torch.cat([torch.zeros_like(coords[:, :1]), coords], dim=-1), *grid_size.tolist())
+
+ # Find connected voxels
+ edge_neighbor_voxel = coords.reshape(N, 1, 1, 3) + flexible_dual_grid_to_mesh.edge_neighbor_voxel_offset # (N, 3, 4, 3)
+ connected_voxel = edge_neighbor_voxel[intersected_flag] # (M, 4, 3)
+ M = connected_voxel.shape[0]
+ connected_voxel_hash_key = torch.cat([
+ torch.zeros((M * 4, 1), dtype=torch.int, device=coords.device),
+ connected_voxel.reshape(-1, 3)
+ ], dim=1)
+ connected_voxel_indices = flexgemm_kernels.hashmap_lookup_3d_cuda(hashmap, connected_voxel_hash_key, *grid_size.tolist()).reshape(M, 4).int()
+ connected_voxel_valid = (connected_voxel_indices != 0xffffffff).all(dim=1)
+ quad_indices = connected_voxel_indices[connected_voxel_valid].int() # (L, 4)
+ L = quad_indices.shape[0]
+
+ # Construct triangles
+ if not train:
+ mesh_vertices = (coords.float() + dual_vertices) * voxel_size + aabb[0].reshape(1, 3)
+ if split_weight is None:
+ # if split 1
+ atempt_triangles_0 = quad_indices[:, flexible_dual_grid_to_mesh.quad_split_1]
+ normals0 = torch.cross(mesh_vertices[atempt_triangles_0[:, 1]] - mesh_vertices[atempt_triangles_0[:, 0]], mesh_vertices[atempt_triangles_0[:, 2]] - mesh_vertices[atempt_triangles_0[:, 0]], dim=1)
+ normals1 = torch.cross(mesh_vertices[atempt_triangles_0[:, 2]] - mesh_vertices[atempt_triangles_0[:, 1]], mesh_vertices[atempt_triangles_0[:, 3]] - mesh_vertices[atempt_triangles_0[:, 1]], dim=1)
+ normals0 = normals0 / torch.norm(normals0, dim=1, keepdim=True)
+ normals1 = normals1 / torch.norm(normals1, dim=1, keepdim=True)
+ align0 = (normals0 * normals1).sum(dim=1, keepdim=True).abs()
+ # if split 2
+ atempt_triangles_1 = quad_indices[:, flexible_dual_grid_to_mesh.quad_split_2]
+ normals0 = torch.cross(mesh_vertices[atempt_triangles_1[:, 1]] - mesh_vertices[atempt_triangles_1[:, 0]], mesh_vertices[atempt_triangles_1[:, 2]] - mesh_vertices[atempt_triangles_1[:, 0]], dim=1)
+ normals1 = torch.cross(mesh_vertices[atempt_triangles_1[:, 2]] - mesh_vertices[atempt_triangles_1[:, 1]], mesh_vertices[atempt_triangles_1[:, 3]] - mesh_vertices[atempt_triangles_1[:, 1]], dim=1)
+ normals0 = normals0 / torch.norm(normals0, dim=1, keepdim=True)
+ normals1 = normals1 / torch.norm(normals1, dim=1, keepdim=True)
+ align1 = (normals0 * normals1).sum(dim=1, keepdim=True).abs()
+ # select split
+ mesh_triangles = torch.where(align0 > align1, atempt_triangles_0, atempt_triangles_1).reshape(-1, 3)
+ else:
+ split_weight_ws = split_weight[quad_indices]
+ split_weight_ws_02 = split_weight_ws[:, 0] * split_weight_ws[:, 2]
+ split_weight_ws_13 = split_weight_ws[:, 1] * split_weight_ws[:, 3]
+ mesh_triangles = torch.where(
+ split_weight_ws_02 > split_weight_ws_13,
+ quad_indices[:, flexible_dual_grid_to_mesh.quad_split_1],
+ quad_indices[:, flexible_dual_grid_to_mesh.quad_split_2]
+ ).reshape(-1, 3)
+ else:
+ assert split_weight is not None, "split_weight must be provided in training mode"
+ mesh_vertices = (coords.float() + dual_vertices) * voxel_size + aabb[0].reshape(1, 3)
+ quad_vs = mesh_vertices[quad_indices]
+ mean_v02 = (quad_vs[:, 0] + quad_vs[:, 2]) / 2
+ mean_v13 = (quad_vs[:, 1] + quad_vs[:, 3]) / 2
+ split_weight_ws = split_weight[quad_indices]
+ split_weight_ws_02 = split_weight_ws[:, 0] * split_weight_ws[:, 2]
+ split_weight_ws_13 = split_weight_ws[:, 1] * split_weight_ws[:, 3]
+ mid_vertices = (
+ split_weight_ws_02 * mean_v02 +
+ split_weight_ws_13 * mean_v13
+ ) / (split_weight_ws_02 + split_weight_ws_13)
+ mesh_vertices = torch.cat([mesh_vertices, mid_vertices], dim=0)
+ quad_indices = torch.cat([quad_indices, torch.arange(N, N + L, device='cuda').unsqueeze(1)], dim=1)
+ mesh_triangles = quad_indices[:, flexible_dual_grid_to_mesh.quad_split_train].reshape(-1, 3)
+
+ return mesh_vertices, mesh_triangles
diff --git a/TRELLIS.2/trellis2/renderers/__init__.py b/TRELLIS.2/trellis2/renderers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..de3203d1bb16065f912bff039e431f609911782d
--- /dev/null
+++ b/TRELLIS.2/trellis2/renderers/__init__.py
@@ -0,0 +1,33 @@
+import importlib
+
+__attributes = {
+ 'MeshRenderer': 'mesh_renderer',
+ 'VoxelRenderer': 'voxel_renderer',
+ 'PbrMeshRenderer': 'pbr_mesh_renderer',
+ 'EnvMap': 'pbr_mesh_renderer',
+}
+
+__submodules = []
+
+__all__ = list(__attributes.keys()) + __submodules
+
+def __getattr__(name):
+ if name not in globals():
+ if name in __attributes:
+ module_name = __attributes[name]
+ module = importlib.import_module(f".{module_name}", __name__)
+ globals()[name] = getattr(module, name)
+ elif name in __submodules:
+ module = importlib.import_module(f".{name}", __name__)
+ globals()[name] = module
+ else:
+ raise AttributeError(f"module {__name__} has no attribute {name}")
+ return globals()[name]
+
+
+# For Pylance
+if __name__ == '__main__':
+ from .mesh_renderer import MeshRenderer
+ from .voxel_renderer import VoxelRenderer
+ from .pbr_mesh_renderer import PbrMeshRenderer, EnvMap
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/renderers/mesh_renderer.py b/TRELLIS.2/trellis2/renderers/mesh_renderer.py
new file mode 100644
index 0000000000000000000000000000000000000000..e20efc59c26fadcbd9c11cbafa2e31b78eec395c
--- /dev/null
+++ b/TRELLIS.2/trellis2/renderers/mesh_renderer.py
@@ -0,0 +1,414 @@
+from typing import *
+import torch
+from easydict import EasyDict as edict
+from ..representations.mesh import Mesh, MeshWithVoxel, MeshWithPbrMaterial, TextureFilterMode, AlphaMode, TextureWrapMode
+import torch.nn.functional as F
+
+
+def intrinsics_to_projection(
+ intrinsics: torch.Tensor,
+ near: float,
+ far: float,
+ ) -> torch.Tensor:
+ """
+ OpenCV intrinsics to OpenGL perspective matrix
+
+ Args:
+ intrinsics (torch.Tensor): [3, 3] OpenCV intrinsics matrix
+ near (float): near plane to clip
+ far (float): far plane to clip
+ Returns:
+ (torch.Tensor): [4, 4] OpenGL perspective matrix
+ """
+ fx, fy = intrinsics[0, 0], intrinsics[1, 1]
+ cx, cy = intrinsics[0, 2], intrinsics[1, 2]
+ ret = torch.zeros((4, 4), dtype=intrinsics.dtype, device=intrinsics.device)
+ ret[0, 0] = 2 * fx
+ ret[1, 1] = 2 * fy
+ ret[0, 2] = 2 * cx - 1
+ ret[1, 2] = - 2 * cy + 1
+ ret[2, 2] = (far + near) / (far - near)
+ ret[2, 3] = 2 * near * far / (near - far)
+ ret[3, 2] = 1.
+ return ret
+
+
+class MeshRenderer:
+ """
+ Renderer for the Mesh representation.
+
+ Args:
+ rendering_options (dict): Rendering options.
+ """
+ def __init__(self, rendering_options={}, device='cuda'):
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+
+ self.rendering_options = edict({
+ "resolution": None,
+ "near": None,
+ "far": None,
+ "ssaa": 1,
+ "chunk_size": None,
+ "antialias": True,
+ "clamp_barycentric_coords": False,
+ })
+ self.rendering_options.update(rendering_options)
+ self.glctx = dr.RasterizeCudaContext(device=device)
+ self.device=device
+
+ def render(
+ self,
+ mesh : Mesh,
+ extrinsics: torch.Tensor,
+ intrinsics: torch.Tensor,
+ return_types = ["mask", "normal", "depth"],
+ transformation : Optional[torch.Tensor] = None
+ ) -> edict:
+ """
+ Render the mesh.
+
+ Args:
+ mesh : meshmodel
+ extrinsics (torch.Tensor): (4, 4) camera extrinsics
+ intrinsics (torch.Tensor): (3, 3) camera intrinsics
+ return_types (list): list of return types, can be "attr", "mask", "depth", "coord", "normal"
+
+ Returns:
+ edict based on return_types containing:
+ attr (torch.Tensor): [C, H, W] rendered attr image
+ depth (torch.Tensor): [H, W] rendered depth image
+ normal (torch.Tensor): [3, H, W] rendered normal image
+ mask (torch.Tensor): [H, W] rendered mask image
+ """
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+
+ resolution = self.rendering_options["resolution"]
+ near = self.rendering_options["near"]
+ far = self.rendering_options["far"]
+ ssaa = self.rendering_options["ssaa"]
+ chunk_size = self.rendering_options["chunk_size"]
+ antialias = self.rendering_options["antialias"]
+ clamp_barycentric_coords = self.rendering_options["clamp_barycentric_coords"]
+
+ if mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
+ ret_dict = edict()
+ for type in return_types:
+ if type == "mask" :
+ ret_dict[type] = torch.zeros((resolution, resolution), dtype=torch.float32, device=self.device)
+ elif type == "depth":
+ ret_dict[type] = torch.zeros((resolution, resolution), dtype=torch.float32, device=self.device)
+ elif type == "normal":
+ ret_dict[type] = torch.full((3, resolution, resolution), 0.5, dtype=torch.float32, device=self.device)
+ elif type == "coord":
+ ret_dict[type] = torch.zeros((3, resolution, resolution), dtype=torch.float32, device=self.device)
+ elif type == "attr":
+ if isinstance(mesh, MeshWithVoxel):
+ ret_dict[type] = torch.zeros((mesh.attrs.shape[-1], resolution, resolution), dtype=torch.float32, device=self.device)
+ else:
+ ret_dict[type] = torch.zeros((mesh.vertex_attrs.shape[-1], resolution, resolution), dtype=torch.float32, device=self.device)
+ return ret_dict
+
+ perspective = intrinsics_to_projection(intrinsics, near, far)
+
+ full_proj = (perspective @ extrinsics).unsqueeze(0)
+ extrinsics = extrinsics.unsqueeze(0)
+
+ vertices = mesh.vertices.unsqueeze(0)
+ vertices_homo = torch.cat([vertices, torch.ones_like(vertices[..., :1])], dim=-1)
+ if transformation is not None:
+ vertices_homo = torch.bmm(vertices_homo, transformation.unsqueeze(0).transpose(-1, -2))
+ vertices = vertices_homo[..., :3].contiguous()
+ vertices_camera = torch.bmm(vertices_homo, extrinsics.transpose(-1, -2))
+ vertices_clip = torch.bmm(vertices_homo, full_proj.transpose(-1, -2))
+ faces = mesh.faces
+
+ if 'normal' in return_types:
+ v0 = vertices_camera[0, mesh.faces[:, 0], :3]
+ v1 = vertices_camera[0, mesh.faces[:, 1], :3]
+ v2 = vertices_camera[0, mesh.faces[:, 2], :3]
+ e0 = v1 - v0
+ e1 = v2 - v0
+ face_normal = torch.cross(e0, e1, dim=1)
+ face_normal = F.normalize(face_normal, dim=1)
+ face_normal = torch.where(torch.sum(face_normal * v0, dim=1, keepdim=True) > 0, face_normal, -face_normal)
+
+ out_dict = edict()
+ if chunk_size is None:
+ rast, rast_db = dr.rasterize(
+ self.glctx, vertices_clip, faces, (resolution * ssaa, resolution * ssaa)
+ )
+ if clamp_barycentric_coords:
+ rast[..., :2] = torch.clamp(rast[..., :2], 0, 1)
+ rast[..., :2] /= torch.where(rast[..., :2].sum(dim=-1, keepdim=True) > 1, rast[..., :2].sum(dim=-1, keepdim=True), torch.ones_like(rast[..., :2]))
+ for type in return_types:
+ img = None
+ if type == "mask" :
+ img = (rast[..., -1:] > 0).float()
+ if antialias: img = dr.antialias(img, rast, vertices_clip, faces)
+ elif type == "depth":
+ img = dr.interpolate(vertices_camera[..., 2:3].contiguous(), rast, faces)[0]
+ if antialias: img = dr.antialias(img, rast, vertices_clip, faces)
+ elif type == "normal" :
+ img = dr.interpolate(face_normal.unsqueeze(0), rast, torch.arange(face_normal.shape[0], dtype=torch.int, device=self.device).unsqueeze(1).repeat(1, 3).contiguous())[0]
+ if antialias: img = dr.antialias(img, rast, vertices_clip, faces)
+ img = (img + 1) / 2
+ elif type == "coord":
+ img = dr.interpolate(vertices, rast, faces)[0]
+ if antialias: img = dr.antialias(img, rast, vertices_clip, faces)
+ elif type == "attr":
+ if isinstance(mesh, MeshWithVoxel):
+ if 'grid_sample_3d' not in globals():
+ from flex_gemm.ops.grid_sample import grid_sample_3d
+ mask = rast[..., -1:] > 0
+ xyz = dr.interpolate(vertices, rast, faces)[0]
+ xyz = ((xyz - mesh.origin) / mesh.voxel_size).reshape(1, -1, 3)
+ img = grid_sample_3d(
+ mesh.attrs,
+ torch.cat([torch.zeros_like(mesh.coords[..., :1]), mesh.coords], dim=-1),
+ mesh.voxel_shape,
+ xyz,
+ mode='trilinear'
+ )
+ img = img.reshape(1, resolution * ssaa, resolution * ssaa, mesh.attrs.shape[-1]) * mask
+ elif isinstance(mesh, MeshWithPbrMaterial):
+ tri_id = rast[0, :, :, -1:]
+ mask = tri_id > 0
+ uv_coords = mesh.uv_coords.reshape(1, -1, 2)
+ texc, texd = dr.interpolate(
+ uv_coords,
+ rast,
+ torch.arange(mesh.uv_coords.shape[0] * 3, dtype=torch.int, device=self.device).reshape(-1, 3),
+ rast_db=rast_db,
+ diff_attrs='all'
+ )
+ # Fix problematic texture coordinates
+ texc = torch.nan_to_num(texc, nan=0.0, posinf=1e3, neginf=-1e3)
+ texc = torch.clamp(texc, min=-1e3, max=1e3)
+ texd = torch.nan_to_num(texd, nan=0.0, posinf=1e3, neginf=-1e3)
+ texd = torch.clamp(texd, min=-1e3, max=1e3)
+ mid = mesh.material_ids[(tri_id - 1).long()]
+ imgs = {
+ 'base_color': torch.zeros((resolution * ssaa, resolution * ssaa, 3), dtype=torch.float32, device=self.device),
+ 'metallic': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device),
+ 'roughness': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device),
+ 'alpha': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ }
+ for id, mat in enumerate(mesh.materials):
+ mat_mask = (mid == id).float() * mask.float()
+ mat_texc = texc * mat_mask
+ mat_texd = texd * mat_mask
+
+ if mat.base_color_texture is not None:
+ base_color = dr.texture(
+ mat.base_color_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.base_color_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.base_color_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['base_color'] += base_color * mat.base_color_factor * mat_mask
+ else:
+ imgs['base_color'] += mat.base_color_factor * mat_mask
+
+ if mat.metallic_texture is not None:
+ metallic = dr.texture(
+ mat.metallic_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.metallic_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.metallic_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['metallic'] += metallic * mat.metallic_factor * mat_mask
+ else:
+ imgs['metallic'] += mat.metallic_factor * mat_mask
+
+ if mat.roughness_texture is not None:
+ roughness = dr.texture(
+ mat.roughness_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.roughness_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.roughness_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['roughness'] += roughness * mat.roughness_factor * mat_mask
+ else:
+ imgs['roughness'] += mat.roughness_factor * mat_mask
+
+ if mat.alpha_mode == AlphaMode.OPAQUE:
+ imgs['alpha'] += 1.0 * mat_mask
+ else:
+ if mat.alpha_texture is not None:
+ alpha = dr.texture(
+ mat.alpha_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.alpha_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.alpha_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ if mat.alpha_mode == AlphaMode.MASK:
+ imgs['alpha'] += (alpha * mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ imgs['alpha'] += alpha * mat.alpha_factor * mat_mask
+ else:
+ if mat.alpha_mode == AlphaMode.MASK:
+ imgs['alpha'] += (mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ imgs['alpha'] += mat.alpha_factor * mat_mask
+
+ img = torch.cat([imgs[name] for name in imgs.keys()], dim=-1).unsqueeze(0)
+ else:
+ img = dr.interpolate(mesh.vertex_attrs.unsqueeze(0), rast, faces)[0]
+ if antialias: img = dr.antialias(img, rast, vertices_clip, faces)
+
+ out_dict[type] = img
+ else:
+ z_buffer = torch.full((1, resolution * ssaa, resolution * ssaa), torch.inf, device=self.device, dtype=torch.float32)
+ for i in range(0, faces.shape[0], chunk_size):
+ faces_chunk = faces[i:i+chunk_size]
+ rast, rast_db = dr.rasterize(
+ self.glctx, vertices_clip, faces_chunk, (resolution * ssaa, resolution * ssaa)
+ )
+ z_filter = torch.logical_and(
+ rast[..., 3] != 0,
+ rast[..., 2] < z_buffer
+ )
+ z_buffer[z_filter] = rast[z_filter][..., 2]
+
+ for type in return_types:
+ img = None
+ if type == "mask" :
+ img = (rast[..., -1:] > 0).float()
+ elif type == "depth":
+ img = dr.interpolate(vertices_camera[..., 2:3].contiguous(), rast, faces_chunk)[0]
+ elif type == "normal" :
+ face_normal_chunk = face_normal[i:i+chunk_size]
+ img = dr.interpolate(face_normal_chunk.unsqueeze(0), rast, torch.arange(face_normal_chunk.shape[0], dtype=torch.int, device=self.device).unsqueeze(1).repeat(1, 3).contiguous())[0]
+ img = (img + 1) / 2
+ elif type == "coord":
+ img = dr.interpolate(vertices, rast, faces_chunk)[0]
+ elif type == "attr":
+ if isinstance(mesh, MeshWithVoxel):
+ if 'grid_sample_3d' not in globals():
+ from flex_gemm.ops.grid_sample import grid_sample_3d
+ mask = rast[..., -1:] > 0
+ xyz = dr.interpolate(vertices, rast, faces_chunk)[0]
+ xyz = ((xyz - mesh.origin) / mesh.voxel_size).reshape(1, -1, 3)
+ img = grid_sample_3d(
+ mesh.attrs,
+ torch.cat([torch.zeros_like(mesh.coords[..., :1]), mesh.coords], dim=-1),
+ mesh.voxel_shape,
+ xyz,
+ mode='trilinear'
+ )
+ img = img.reshape(1, resolution * ssaa, resolution * ssaa, mesh.attrs.shape[-1]) * mask
+ elif isinstance(mesh, MeshWithPbrMaterial):
+ tri_id = rast[0, :, :, -1:]
+ mask = tri_id > 0
+ uv_coords = mesh.uv_coords.reshape(1, -1, 2)
+ texc, texd = dr.interpolate(
+ uv_coords,
+ rast,
+ torch.arange(mesh.uv_coords.shape[0] * 3, dtype=torch.int, device=self.device).reshape(-1, 3),
+ rast_db=rast_db,
+ diff_attrs='all'
+ )
+ # Fix problematic texture coordinates
+ texc = torch.nan_to_num(texc, nan=0.0, posinf=1e3, neginf=-1e3)
+ texc = torch.clamp(texc, min=-1e3, max=1e3)
+ texd = torch.nan_to_num(texd, nan=0.0, posinf=1e3, neginf=-1e3)
+ texd = torch.clamp(texd, min=-1e3, max=1e3)
+ mid = mesh.material_ids[(tri_id - 1).long()]
+ imgs = {
+ 'base_color': torch.zeros((resolution * ssaa, resolution * ssaa, 3), dtype=torch.float32, device=self.device),
+ 'metallic': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device),
+ 'roughness': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device),
+ 'alpha': torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ }
+ for id, mat in enumerate(mesh.materials):
+ mat_mask = (mid == id).float() * mask.float()
+ mat_texc = texc * mat_mask
+ mat_texd = texd * mat_mask
+
+ if mat.base_color_texture is not None:
+ base_color = dr.texture(
+ mat.base_color_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.base_color_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.base_color_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['base_color'] += base_color * mat.base_color_factor * mat_mask
+ else:
+ imgs['base_color'] += mat.base_color_factor * mat_mask
+
+ if mat.metallic_texture is not None:
+ metallic = dr.texture(
+ mat.metallic_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.metallic_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.metallic_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['metallic'] += metallic * mat.metallic_factor * mat_mask
+ else:
+ imgs['metallic'] += mat.metallic_factor * mat_mask
+
+ if mat.roughness_texture is not None:
+ roughness = dr.texture(
+ mat.roughness_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.roughness_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.roughness_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ imgs['roughness'] += roughness * mat.roughness_factor * mat_mask
+ else:
+ imgs['roughness'] += mat.roughness_factor * mat_mask
+
+ if mat.alpha_mode == AlphaMode.OPAQUE:
+ imgs['alpha'] += 1.0 * mat_mask
+ else:
+ if mat.alpha_texture is not None:
+ alpha = dr.texture(
+ mat.alpha_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.alpha_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.alpha_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ if mat.alpha_mode == AlphaMode.MASK:
+ imgs['alpha'] += (alpha * mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ imgs['alpha'] += alpha * mat.alpha_factor * mat_mask
+ else:
+ if mat.alpha_mode == AlphaMode.MASK:
+ imgs['alpha'] += (mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ imgs['alpha'] += mat.alpha_factor * mat_mask
+
+ img = torch.cat([imgs[name] for name in imgs.keys()], dim=-1).unsqueeze(0)
+ else:
+ img = dr.interpolate(mesh.vertex_attrs.unsqueeze(0), rast, faces_chunk)[0]
+
+ if type not in out_dict:
+ out_dict[type] = img
+ else:
+ out_dict[type][z_filter] = img[z_filter]
+
+ for type in return_types:
+ img = out_dict[type]
+ if ssaa > 1:
+ img = F.interpolate(img.permute(0, 3, 1, 2), (resolution, resolution), mode='bilinear', align_corners=False, antialias=True)
+ img = img.squeeze()
+ else:
+ img = img.permute(0, 3, 1, 2).squeeze()
+ out_dict[type] = img
+
+ if isinstance(mesh, (MeshWithVoxel, MeshWithPbrMaterial)) and 'attr' in return_types:
+ for k, s in mesh.layout.items():
+ out_dict[k] = out_dict['attr'][s]
+ del out_dict['attr']
+
+ return out_dict
diff --git a/TRELLIS.2/trellis2/renderers/pbr_mesh_renderer.py b/TRELLIS.2/trellis2/renderers/pbr_mesh_renderer.py
new file mode 100644
index 0000000000000000000000000000000000000000..876378fd6bba32b9dcb75cf84a3630f1d3d84026
--- /dev/null
+++ b/TRELLIS.2/trellis2/renderers/pbr_mesh_renderer.py
@@ -0,0 +1,480 @@
+from typing import *
+import torch
+from easydict import EasyDict as edict
+import numpy as np
+import utils3d
+from ..representations.mesh import Mesh, MeshWithVoxel, MeshWithPbrMaterial, TextureFilterMode, AlphaMode, TextureWrapMode
+import torch.nn.functional as F
+
+
+def cube_to_dir(s, x, y):
+ if s == 0: rx, ry, rz = torch.ones_like(x), -x, -y
+ elif s == 1: rx, ry, rz = -torch.ones_like(x), x, -y
+ elif s == 2: rx, ry, rz = x, y, torch.ones_like(x)
+ elif s == 3: rx, ry, rz = x, -y, -torch.ones_like(x)
+ elif s == 4: rx, ry, rz = x, torch.ones_like(x), -y
+ elif s == 5: rx, ry, rz = -x, -torch.ones_like(x), -y
+ return torch.stack((rx, ry, rz), dim=-1)
+
+
+def latlong_to_cubemap(latlong_map, res):
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+ cubemap = torch.zeros(6, res[0], res[1], latlong_map.shape[-1], dtype=torch.float32, device='cuda')
+ for s in range(6):
+ gy, gx = torch.meshgrid(torch.linspace(-1.0 + 1.0 / res[0], 1.0 - 1.0 / res[0], res[0], device='cuda'),
+ torch.linspace(-1.0 + 1.0 / res[1], 1.0 - 1.0 / res[1], res[1], device='cuda'),
+ indexing='ij')
+ v = F.normalize(cube_to_dir(s, gx, gy), dim=-1)
+
+ tu = torch.atan2(v[..., 0:1], -v[..., 2:3]) / (2 * np.pi) + 0.5
+ tv = torch.acos(torch.clamp(v[..., 1:2], min=-1, max=1)) / np.pi
+ texcoord = torch.cat((tu, tv), dim=-1)
+
+ cubemap[s, ...] = dr.texture(latlong_map[None, ...], texcoord[None, ...], filter_mode='linear')[0]
+ return cubemap
+
+
+class EnvMap:
+ def __init__(self, image: torch.Tensor):
+ self.image = image
+
+ @property
+ def _backend(self):
+ if not hasattr(self, '_nvdiffrec_envlight'):
+ if 'EnvironmentLight' not in globals():
+ from nvdiffrec_render.light import EnvironmentLight
+ cubemap = latlong_to_cubemap(self.image, [512, 512])
+ self._nvdiffrec_envlight = EnvironmentLight(cubemap)
+ self._nvdiffrec_envlight.build_mips()
+ return self._nvdiffrec_envlight
+
+ def shade(self, gb_pos, gb_normal, kd, ks, view_pos, specular=True):
+ return self._backend.shade(gb_pos, gb_normal, kd, ks, view_pos, specular)
+
+ def sample(self, directions: torch.Tensor):
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+ return dr.texture(
+ self._backend.base.unsqueeze(0),
+ directions.unsqueeze(0),
+ boundary_mode='cube',
+ )[0]
+
+
+def intrinsics_to_projection(
+ intrinsics: torch.Tensor,
+ near: float,
+ far: float,
+ ) -> torch.Tensor:
+ """
+ OpenCV intrinsics to OpenGL perspective matrix
+
+ Args:
+ intrinsics (torch.Tensor): [3, 3] OpenCV intrinsics matrix
+ near (float): near plane to clip
+ far (float): far plane to clip
+ Returns:
+ (torch.Tensor): [4, 4] OpenGL perspective matrix
+ """
+ fx, fy = intrinsics[0, 0], intrinsics[1, 1]
+ cx, cy = intrinsics[0, 2], intrinsics[1, 2]
+ ret = torch.zeros((4, 4), dtype=intrinsics.dtype, device=intrinsics.device)
+ ret[0, 0] = 2 * fx
+ ret[1, 1] = 2 * fy
+ ret[0, 2] = 2 * cx - 1
+ ret[1, 2] = - 2 * cy + 1
+ ret[2, 2] = (far + near) / (far - near)
+ ret[2, 3] = 2 * near * far / (near - far)
+ ret[3, 2] = 1.
+ return ret
+
+
+def screen_space_ambient_occlusion(
+ depth: torch.Tensor,
+ normal: torch.Tensor,
+ perspective: torch.Tensor,
+ radius: float = 0.1,
+ bias: float = 1e-6,
+ samples: int = 64,
+ intensity: float = 1.0,
+) -> torch.Tensor:
+ """
+ Screen space ambient occlusion (SSAO)
+
+ Args:
+ depth (torch.Tensor): [H, W, 1] depth image
+ normal (torch.Tensor): [H, W, 3] normal image
+ perspective (torch.Tensor): [4, 4] camera projection matrix
+ radius (float): radius of the SSAO kernel
+ bias (float): bias to avoid self-occlusion
+ samples (int): number of samples to use for the SSAO kernel
+ intensity (float): intensity of the SSAO effect
+ Returns:
+ (torch.Tensor): [H, W, 1] SSAO image
+ """
+ device = depth.device
+ H, W, _ = depth.shape
+
+ fx = perspective[0, 0]
+ fy = perspective[1, 1]
+ cx = perspective[0, 2]
+ cy = perspective[1, 2]
+
+ y_grid, x_grid = torch.meshgrid(
+ (torch.arange(H, device=device) + 0.5) / H * 2 - 1,
+ (torch.arange(W, device=device) + 0.5) / W * 2 - 1,
+ indexing='ij'
+ )
+ x_view = (x_grid.float() - cx) * depth[..., 0] / fx
+ y_view = (y_grid.float() - cy) * depth[..., 0] / fy
+ view_pos = torch.stack([x_view, y_view, depth[..., 0]], dim=-1) # [H, W, 3]
+
+ depth_feat = depth.permute(2, 0, 1).unsqueeze(0)
+ occlusion = torch.zeros((H, W), device=device)
+
+ # start sampling
+ for _ in range(samples):
+ # sample normal distribution, if inside, flip the sign
+ rnd_vec = torch.randn(H, W, 3, device=device)
+ rnd_vec = F.normalize(rnd_vec, p=2, dim=-1)
+ dot_val = torch.sum(rnd_vec * normal, dim=-1, keepdim=True)
+ sample_dir = torch.sign(dot_val) * rnd_vec
+ scale = torch.rand(H, W, 1, device=device)
+ scale = scale * scale
+ sample_pos = view_pos + sample_dir * radius * scale
+ sample_z = sample_pos[..., 2]
+
+ # project to screen space
+ z_safe = torch.clamp(sample_pos[..., 2], min=1e-5)
+ proj_u = (sample_pos[..., 0] * fx / z_safe) + cx
+ proj_v = (sample_pos[..., 1] * fy / z_safe) + cy
+ grid = torch.stack([proj_u, proj_v], dim=-1).unsqueeze(0)
+ geo_z = F.grid_sample(depth_feat, grid, mode='nearest', padding_mode='border').squeeze()
+ range_check = torch.abs(geo_z - sample_z) < radius
+ is_occluded = (geo_z <= sample_z - bias) & range_check
+ occlusion += is_occluded.float()
+
+ f_occ = occlusion / samples * intensity
+ f_occ = torch.clamp(f_occ, 0.0, 1.0)
+
+ return f_occ.unsqueeze(-1)
+
+
+def aces_tonemapping(x: torch.Tensor) -> torch.Tensor:
+ """
+ Applies ACES tone mapping curve to an HDR image tensor.
+ Input: x - HDR tensor, shape (..., 3), range [0, +inf)
+ Output: LDR tensor, same shape, range [0, 1]
+ """
+ a = 2.51
+ b = 0.03
+ c = 2.43
+ d = 0.59
+ e = 0.14
+
+ # Apply the ACES fitted curve
+ mapped = (x * (a * x + b)) / (x * (c * x + d) + e)
+
+ # Clamp to [0, 1] for display or saving
+ return torch.clamp(mapped, 0.0, 1.0)
+
+
+def gamma_correction(x: torch.Tensor, gamma: float = 2.2) -> torch.Tensor:
+ """
+ Applies gamma correction to an HDR image tensor.
+ """
+ return torch.clamp(x ** (1.0 / gamma), 0.0, 1.0)
+
+
+class PbrMeshRenderer:
+ """
+ Renderer for the PBR mesh.
+
+ Args:
+ rendering_options (dict): Rendering options.
+ """
+ def __init__(self, rendering_options={}, device='cuda'):
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+
+ self.rendering_options = edict({
+ "resolution": None,
+ "near": None,
+ "far": None,
+ "ssaa": 1,
+ "peel_layers": 8,
+ })
+ self.rendering_options.update(rendering_options)
+ self.glctx = dr.RasterizeCudaContext(device=device)
+ self.device=device
+
+ def render(
+ self,
+ mesh : Mesh,
+ extrinsics: torch.Tensor,
+ intrinsics: torch.Tensor,
+ envmap : Union[EnvMap, Dict[str, EnvMap]],
+ use_envmap_bg : bool = False,
+ transformation : Optional[torch.Tensor] = None
+ ) -> edict:
+ """
+ Render the mesh.
+
+ Args:
+ mesh : meshmodel
+ extrinsics (torch.Tensor): (4, 4) camera extrinsics
+ intrinsics (torch.Tensor): (3, 3) camera intrinsics
+ envmap (Union[EnvMap, Dict[str, EnvMap]]): environment map or a dictionary of environment maps
+ use_envmap_bg (bool): whether to use envmap as background
+ transformation (torch.Tensor): (4, 4) transformation matrix
+
+ Returns:
+ edict based on return_types containing:
+ shaded (torch.Tensor): [3, H, W] shaded color image
+ normal (torch.Tensor): [3, H, W] normal image
+ base_color (torch.Tensor): [3, H, W] base color image
+ metallic (torch.Tensor): [H, W] metallic image
+ roughness (torch.Tensor): [H, W] roughness image
+ """
+ if 'dr' not in globals():
+ import nvdiffrast.torch as dr
+
+ if not isinstance(envmap, dict):
+ envmap = {'' : envmap}
+ num_envmaps = len(envmap)
+
+ resolution = self.rendering_options["resolution"]
+ near = self.rendering_options["near"]
+ far = self.rendering_options["far"]
+ ssaa = self.rendering_options["ssaa"]
+
+ if mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
+ return edict(
+ shaded=torch.full((4, resolution, resolution), 0.5, dtype=torch.float32, device=self.device),
+ )
+
+ rays_o, rays_d = utils3d.torch.get_image_rays(
+ extrinsics, intrinsics, resolution * ssaa, resolution * ssaa
+ )
+
+ perspective = intrinsics_to_projection(intrinsics, near, far)
+
+ full_proj = (perspective @ extrinsics).unsqueeze(0)
+ extrinsics = extrinsics.unsqueeze(0)
+
+ vertices = mesh.vertices.unsqueeze(0)
+ vertices_orig = vertices.clone()
+ vertices_homo = torch.cat([vertices, torch.ones_like(vertices[..., :1])], dim=-1)
+ if transformation is not None:
+ vertices_homo = torch.bmm(vertices_homo, transformation.unsqueeze(0).transpose(-1, -2))
+ vertices = vertices_homo[..., :3].contiguous()
+ vertices_camera = torch.bmm(vertices_homo, extrinsics.transpose(-1, -2))
+ vertices_clip = torch.bmm(vertices_homo, full_proj.transpose(-1, -2))
+ faces = mesh.faces
+
+ v0 = vertices[0, mesh.faces[:, 0], :3]
+ v1 = vertices[0, mesh.faces[:, 1], :3]
+ v2 = vertices[0, mesh.faces[:, 2], :3]
+ e0 = v1 - v0
+ e1 = v2 - v0
+ face_normal = torch.cross(e0, e1, dim=1)
+ face_normal = F.normalize(face_normal, dim=1)
+
+ out_dict = edict()
+ shaded = torch.zeros((num_envmaps, resolution * ssaa, resolution * ssaa, 3), dtype=torch.float32, device=self.device)
+ depth = torch.full((resolution * ssaa, resolution * ssaa, 1), 1e10, dtype=torch.float32, device=self.device)
+ normal = torch.zeros((resolution * ssaa, resolution * ssaa, 3), dtype=torch.float32, device=self.device)
+ max_w = torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ alpha = torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ with dr.DepthPeeler(self.glctx, vertices_clip, faces, (resolution * ssaa, resolution * ssaa)) as peeler:
+ for _ in range(self.rendering_options["peel_layers"]):
+ rast, rast_db = peeler.rasterize_next_layer()
+
+ # Pos
+ pos = dr.interpolate(vertices, rast, faces)[0][0]
+
+ # Depth
+ gb_depth = dr.interpolate(vertices_camera[..., 2:3].contiguous(), rast, faces)[0][0]
+
+ # Normal
+ gb_normal = dr.interpolate(face_normal.unsqueeze(0), rast, torch.arange(face_normal.shape[0], dtype=torch.int, device=self.device).unsqueeze(1).repeat(1, 3).contiguous())[0][0]
+ gb_normal = torch.where(
+ torch.sum(gb_normal * (pos - rays_o), dim=-1, keepdim=True) > 0,
+ -gb_normal,
+ gb_normal
+ )
+ gb_cam_normal = (extrinsics[..., :3, :3].reshape(1, 1, 3, 3) @ gb_normal.unsqueeze(-1)).squeeze(-1)
+ if _ == 0:
+ out_dict.normal = -gb_cam_normal * 0.5 + 0.5
+ mask = (rast[0, ..., -1:] > 0).float()
+ out_dict.mask = mask
+
+ # PBR attributes
+ if isinstance(mesh, MeshWithVoxel):
+ if 'grid_sample_3d' not in globals():
+ from flex_gemm.ops.grid_sample import grid_sample_3d
+ mask = rast[..., -1:] > 0
+ xyz = dr.interpolate(vertices_orig, rast, faces)[0]
+ xyz = ((xyz - mesh.origin) / mesh.voxel_size).reshape(1, -1, 3)
+ img = grid_sample_3d(
+ mesh.attrs,
+ torch.cat([torch.zeros_like(mesh.coords[..., :1]), mesh.coords], dim=-1),
+ mesh.voxel_shape,
+ xyz,
+ mode='trilinear'
+ )
+ img = img.reshape(1, resolution * ssaa, resolution * ssaa, mesh.attrs.shape[-1]) * mask
+ gb_basecolor = img[0, ..., mesh.layout['base_color']]
+ gb_metallic = img[0, ..., mesh.layout['metallic']]
+ gb_roughness = img[0, ..., mesh.layout['roughness']]
+ gb_alpha = img[0, ..., mesh.layout['alpha']]
+ elif isinstance(mesh, MeshWithPbrMaterial):
+ tri_id = rast[0, :, :, -1:]
+ mask = tri_id > 0
+ uv_coords = mesh.uv_coords.reshape(1, -1, 2)
+ texc, texd = dr.interpolate(
+ uv_coords,
+ rast,
+ torch.arange(mesh.uv_coords.shape[0] * 3, dtype=torch.int, device=self.device).reshape(-1, 3),
+ rast_db=rast_db,
+ diff_attrs='all'
+ )
+ # Fix problematic texture coordinates
+ texc = torch.nan_to_num(texc, nan=0.0, posinf=1e3, neginf=-1e3)
+ texc = torch.clamp(texc, min=-1e3, max=1e3)
+ texd = torch.nan_to_num(texd, nan=0.0, posinf=1e3, neginf=-1e3)
+ texd = torch.clamp(texd, min=-1e3, max=1e3)
+ mid = mesh.material_ids[(tri_id - 1).long()]
+ gb_basecolor = torch.zeros((resolution * ssaa, resolution * ssaa, 3), dtype=torch.float32, device=self.device)
+ gb_metallic = torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ gb_roughness = torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ gb_alpha = torch.zeros((resolution * ssaa, resolution * ssaa, 1), dtype=torch.float32, device=self.device)
+ for id, mat in enumerate(mesh.materials):
+ mat_mask = (mid == id).float() * mask.float()
+ mat_texc = texc * mat_mask
+ mat_texd = texd * mat_mask
+
+ if mat.base_color_texture is not None:
+ bc = dr.texture(
+ mat.base_color_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.base_color_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.base_color_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ gb_basecolor += bc * mat.base_color_factor * mat_mask
+ else:
+ gb_basecolor += mat.base_color_factor * mat_mask
+
+ if mat.metallic_texture is not None:
+ m = dr.texture(
+ mat.metallic_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.metallic_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.metallic_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ gb_metallic += m * mat.metallic_factor * mat_mask
+ else:
+ gb_metallic += mat.metallic_factor * mat_mask
+
+ if mat.roughness_texture is not None:
+ r = dr.texture(
+ mat.roughness_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.roughness_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.roughness_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ gb_roughness += r * mat.roughness_factor * mat_mask
+ else:
+ gb_roughness += mat.roughness_factor * mat_mask
+
+ if mat.alpha_mode == AlphaMode.OPAQUE:
+ gb_alpha += 1.0 * mat_mask
+ else:
+ if mat.alpha_texture is not None:
+ a = dr.texture(
+ mat.alpha_texture.image.unsqueeze(0),
+ mat_texc,
+ mat_texd,
+ filter_mode='linear-mipmap-linear' if mat.alpha_texture.filter_mode == TextureFilterMode.LINEAR else 'nearest',
+ boundary_mode='clamp' if mat.alpha_texture.wrap_mode == TextureWrapMode.CLAMP_TO_EDGE else 'wrap'
+ )[0]
+ if mat.alpha_mode == AlphaMode.MASK:
+ gb_alpha += (a * mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ gb_alpha += a * mat.alpha_factor * mat_mask
+ else:
+ if mat.alpha_mode == AlphaMode.MASK:
+ gb_alpha += (mat.alpha_factor > mat.alpha_cutoff).float() * mat_mask
+ elif mat.alpha_mode == AlphaMode.BLEND:
+ gb_alpha += mat.alpha_factor * mat_mask
+ if _ == 0:
+ out_dict.base_color = gb_basecolor
+ out_dict.metallic = gb_metallic
+ out_dict.roughness = gb_roughness
+ out_dict.alpha = gb_alpha
+
+ # Shading
+ gb_basecolor = torch.clamp(gb_basecolor, 0.0, 1.0) ** 2.2
+ gb_metallic = torch.clamp(gb_metallic, 0.0, 1.0)
+ gb_roughness = torch.clamp(gb_roughness, 0.0, 1.0)
+ gb_alpha = torch.clamp(gb_alpha, 0.0, 1.0)
+ gb_orm = torch.cat([
+ torch.zeros_like(gb_metallic),
+ gb_roughness,
+ gb_metallic,
+ ], dim=-1)
+ gb_shaded = torch.stack([
+ e.shade(
+ pos.unsqueeze(0),
+ gb_normal.unsqueeze(0),
+ gb_basecolor.unsqueeze(0),
+ gb_orm.unsqueeze(0),
+ rays_o,
+ specular=True,
+ )[0]
+ for e in envmap.values()
+ ], dim=0)
+
+ # Compositing
+ w = (1 - alpha) * gb_alpha
+ depth = torch.where(w > max_w, gb_depth, depth)
+ normal = torch.where(w > max_w, gb_cam_normal, normal)
+ max_w = torch.maximum(max_w, w)
+ shaded += w * gb_shaded
+ alpha += w
+
+ # Ambient occulusion
+ f_occ = screen_space_ambient_occlusion(
+ depth, normal, perspective, intensity=1.5
+ )
+ shaded *= (1 - f_occ)
+ out_dict.clay = (1 - f_occ)
+
+ # Background
+ if use_envmap_bg:
+ bg = torch.stack([e.sample(rays_d) for e in envmap.values()], dim=0)
+ shaded += (1 - alpha) * bg
+
+ for i, k in enumerate(envmap.keys()):
+ shaded_key = f"shaded_{k}" if k != '' else "shaded"
+ out_dict[shaded_key] = shaded[i]
+
+ # SSAA
+ for k in out_dict.keys():
+ if ssaa > 1:
+ out_dict[k] = F.interpolate(out_dict[k].unsqueeze(0).permute(0, 3, 1, 2), (resolution, resolution), mode='bilinear', align_corners=False, antialias=True)
+ else:
+ out_dict[k] = out_dict[k].permute(2, 0, 1)
+ out_dict[k] = out_dict[k].squeeze()
+
+ # Post processing
+ for k in envmap.keys():
+ shaded_key = f"shaded_{k}" if k != '' else "shaded"
+ out_dict[shaded_key] = aces_tonemapping(out_dict[shaded_key])
+ out_dict[shaded_key] = gamma_correction(out_dict[shaded_key])
+
+ return out_dict
diff --git a/TRELLIS.2/trellis2/renderers/voxel_renderer.py b/TRELLIS.2/trellis2/renderers/voxel_renderer.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfe28ad8d341ed62c1d7a5ab739fed6cace30a5f
--- /dev/null
+++ b/TRELLIS.2/trellis2/renderers/voxel_renderer.py
@@ -0,0 +1,68 @@
+import torch
+from easydict import EasyDict as edict
+from ..representations import Voxel
+from easydict import EasyDict as edict
+
+
+class VoxelRenderer:
+ """
+ Renderer for the Voxel representation.
+
+ Args:
+ rendering_options (dict): Rendering options.
+ """
+
+ def __init__(self, rendering_options={}) -> None:
+ self.rendering_options = edict({
+ "resolution": None,
+ "near": 0.1,
+ "far": 10.0,
+ "ssaa": 1,
+ })
+ self.rendering_options.update(rendering_options)
+
+ def render(
+ self,
+ voxel: Voxel,
+ extrinsics: torch.Tensor,
+ intrinsics: torch.Tensor,
+ colors_overwrite: torch.Tensor = None
+ ) -> edict:
+ """
+ Render the gausssian.
+
+ Args:
+ voxel (Voxel): Voxel representation.
+ extrinsics (torch.Tensor): (4, 4) camera extrinsics
+ intrinsics (torch.Tensor): (3, 3) camera intrinsics
+ colors_overwrite (torch.Tensor): (N, 3) override color
+
+ Returns:
+ edict containing:
+ color (torch.Tensor): (3, H, W) rendered color image
+ depth (torch.Tensor): (H, W) rendered depth
+ alpha (torch.Tensor): (H, W) rendered alpha
+ ...
+ """
+ # lazy import
+ if 'o_voxel' not in globals():
+ import o_voxel
+ renderer = o_voxel.rasterize.VoxelRenderer(self.rendering_options)
+ positions = voxel.position
+ attrs = voxel.attrs if colors_overwrite is None else colors_overwrite
+ voxel_size = voxel.voxel_size
+
+ # Render
+ render_ret = renderer.render(positions, attrs, voxel_size, extrinsics, intrinsics)
+
+ ret = {
+ 'depth': render_ret['depth'],
+ 'alpha': render_ret['alpha'],
+ }
+ if colors_overwrite is not None:
+ ret['color'] = render_ret['attr']
+ else:
+ for k, s in voxel.layout.items():
+ ret[k] = render_ret['attr'][s]
+
+ return ret
diff --git a/TRELLIS.2/trellis2/representations/__init__.py b/TRELLIS.2/trellis2/representations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e7d9299f866c344e81e27f748f837e5ce81ed8b
--- /dev/null
+++ b/TRELLIS.2/trellis2/representations/__init__.py
@@ -0,0 +1,31 @@
+import importlib
+
+__attributes = {
+ 'Mesh': 'mesh',
+ 'Voxel': 'voxel',
+ 'MeshWithVoxel': 'mesh',
+ 'MeshWithPbrMaterial': 'mesh',
+}
+
+__submodules = []
+
+__all__ = list(__attributes.keys()) + __submodules
+
+def __getattr__(name):
+ if name not in globals():
+ if name in __attributes:
+ module_name = __attributes[name]
+ module = importlib.import_module(f".{module_name}", __name__)
+ globals()[name] = getattr(module, name)
+ elif name in __submodules:
+ module = importlib.import_module(f".{name}", __name__)
+ globals()[name] = module
+ else:
+ raise AttributeError(f"module {__name__} has no attribute {name}")
+ return globals()[name]
+
+
+# For Pylance
+if __name__ == '__main__':
+ from .mesh import Mesh, MeshWithVoxel, MeshWithPbrMaterial
+ from .voxel import Voxel
diff --git a/TRELLIS.2/trellis2/representations/mesh/__init__.py b/TRELLIS.2/trellis2/representations/mesh/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..aff4c99a97f764a7c695d87d6a60bd03d61e2106
--- /dev/null
+++ b/TRELLIS.2/trellis2/representations/mesh/__init__.py
@@ -0,0 +1 @@
+from .base import Mesh, MeshWithVoxel, MeshWithPbrMaterial, TextureFilterMode, TextureWrapMode, AlphaMode, PbrMaterial, Texture
diff --git a/TRELLIS.2/trellis2/representations/mesh/base.py b/TRELLIS.2/trellis2/representations/mesh/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..b70e4cca19d65b47d07f297894b831d3506be5ff
--- /dev/null
+++ b/TRELLIS.2/trellis2/representations/mesh/base.py
@@ -0,0 +1,234 @@
+from typing import *
+import torch
+from ..voxel import Voxel
+import cumesh
+from flex_gemm.ops.grid_sample import grid_sample_3d
+
+
+class Mesh:
+ def __init__(self,
+ vertices,
+ faces,
+ vertex_attrs=None
+ ):
+ self.vertices = vertices.float()
+ self.faces = faces.int()
+ self.vertex_attrs = vertex_attrs
+
+ @property
+ def device(self):
+ return self.vertices.device
+
+ def to(self, device, non_blocking=False):
+ return Mesh(
+ self.vertices.to(device, non_blocking=non_blocking),
+ self.faces.to(device, non_blocking=non_blocking),
+ self.vertex_attrs.to(device, non_blocking=non_blocking) if self.vertex_attrs is not None else None,
+ )
+
+ def cuda(self, non_blocking=False):
+ return self.to('cuda', non_blocking=non_blocking)
+
+ def cpu(self):
+ return self.to('cpu')
+
+ def fill_holes(self, max_hole_perimeter=3e-2):
+ vertices = self.vertices.cuda()
+ faces = self.faces.cuda()
+
+ mesh = cumesh.CuMesh()
+ mesh.init(vertices, faces)
+ mesh.get_edges()
+ mesh.get_boundary_info()
+ if mesh.num_boundaries == 0:
+ return
+ mesh.get_vertex_edge_adjacency()
+ mesh.get_vertex_boundary_adjacency()
+ mesh.get_manifold_boundary_adjacency()
+ mesh.read_manifold_boundary_adjacency()
+ mesh.get_boundary_connected_components()
+ mesh.get_boundary_loops()
+ if mesh.num_boundary_loops == 0:
+ return
+ mesh.fill_holes(max_hole_perimeter=max_hole_perimeter)
+ new_vertices, new_faces = mesh.read()
+
+ self.vertices = new_vertices.to(self.device)
+ self.faces = new_faces.to(self.device)
+
+ def remove_faces(self, face_mask: torch.Tensor):
+ vertices = self.vertices.cuda()
+ faces = self.faces.cuda()
+
+ mesh = cumesh.CuMesh()
+ mesh.init(vertices, faces)
+ mesh.remove_faces(face_mask)
+ new_vertices, new_faces = mesh.read()
+
+ self.vertices = new_vertices.to(self.device)
+ self.faces = new_faces.to(self.device)
+
+ def simplify(self, target=1000000, verbose: bool=False, options: dict={}):
+ vertices = self.vertices.cuda()
+ faces = self.faces.cuda()
+
+ mesh = cumesh.CuMesh()
+ mesh.init(vertices, faces)
+ mesh.simplify(target, verbose=verbose, options=options)
+ new_vertices, new_faces = mesh.read()
+
+ self.vertices = new_vertices.to(self.device)
+ self.faces = new_faces.to(self.device)
+
+
+class TextureFilterMode:
+ CLOSEST = 0
+ LINEAR = 1
+
+
+class TextureWrapMode:
+ CLAMP_TO_EDGE = 0
+ REPEAT = 1
+ MIRRORED_REPEAT = 2
+
+
+class AlphaMode:
+ OPAQUE = 0
+ MASK = 1
+ BLEND = 2
+
+
+class Texture:
+ def __init__(
+ self,
+ image: torch.Tensor,
+ filter_mode: TextureFilterMode = TextureFilterMode.LINEAR,
+ wrap_mode: TextureWrapMode = TextureWrapMode.REPEAT
+ ):
+ self.image = image
+ self.filter_mode = filter_mode
+ self.wrap_mode = wrap_mode
+
+ def to(self, device, non_blocking=False):
+ return Texture(
+ self.image.to(device, non_blocking=non_blocking),
+ self.filter_mode,
+ self.wrap_mode,
+ )
+
+
+class PbrMaterial:
+ def __init__(
+ self,
+ base_color_texture: Optional[Texture] = None,
+ base_color_factor: Union[torch.Tensor, List[float]] = [1.0, 1.0, 1.0],
+ metallic_texture: Optional[Texture] = None,
+ metallic_factor: float = 1.0,
+ roughness_texture: Optional[Texture] = None,
+ roughness_factor: float = 1.0,
+ alpha_texture: Optional[Texture] = None,
+ alpha_factor: float = 1.0,
+ alpha_mode: AlphaMode = AlphaMode.OPAQUE,
+ alpha_cutoff: float = 0.5,
+ ):
+ self.base_color_texture = base_color_texture
+ self.base_color_factor = torch.tensor(base_color_factor, dtype=torch.float32)[:3]
+ self.metallic_texture = metallic_texture
+ self.metallic_factor = metallic_factor
+ self.roughness_texture = roughness_texture
+ self.roughness_factor = roughness_factor
+ self.alpha_texture = alpha_texture
+ self.alpha_factor = alpha_factor
+ self.alpha_mode = alpha_mode
+ self.alpha_cutoff = alpha_cutoff
+
+ def to(self, device, non_blocking=False):
+ return PbrMaterial(
+ base_color_texture=self.base_color_texture.to(device, non_blocking=non_blocking) if self.base_color_texture is not None else None,
+ base_color_factor=self.base_color_factor.to(device, non_blocking=non_blocking),
+ metallic_texture=self.metallic_texture.to(device, non_blocking=non_blocking) if self.metallic_texture is not None else None,
+ metallic_factor=self.metallic_factor,
+ roughness_texture=self.roughness_texture.to(device, non_blocking=non_blocking) if self.roughness_texture is not None else None,
+ roughness_factor=self.roughness_factor,
+ alpha_texture=self.alpha_texture.to(device, non_blocking=non_blocking) if self.alpha_texture is not None else None,
+ alpha_factor=self.alpha_factor,
+ alpha_mode=self.alpha_mode,
+ alpha_cutoff=self.alpha_cutoff,
+ )
+
+
+class MeshWithPbrMaterial(Mesh):
+ def __init__(self,
+ vertices,
+ faces,
+ material_ids,
+ uv_coords,
+ materials: List[PbrMaterial],
+ ):
+ self.vertices = vertices.float()
+ self.faces = faces.int()
+ self.material_ids = material_ids # [M]
+ self.uv_coords = uv_coords # [M, 3, 2]
+ self.materials = materials
+ self.layout = {
+ 'base_color': slice(0, 3),
+ 'metallic': slice(3, 4),
+ 'roughness': slice(4, 5),
+ 'alpha': slice(5, 6),
+ }
+
+ def to(self, device, non_blocking=False):
+ return MeshWithPbrMaterial(
+ self.vertices.to(device, non_blocking=non_blocking),
+ self.faces.to(device, non_blocking=non_blocking),
+ self.material_ids.to(device, non_blocking=non_blocking),
+ self.uv_coords.to(device, non_blocking=non_blocking),
+ [material.to(device, non_blocking=non_blocking) for material in self.materials],
+ )
+
+
+class MeshWithVoxel(Mesh, Voxel):
+ def __init__(self,
+ vertices: torch.Tensor,
+ faces: torch.Tensor,
+ origin: list,
+ voxel_size: float,
+ coords: torch.Tensor,
+ attrs: torch.Tensor,
+ voxel_shape: torch.Size,
+ layout: Dict = {},
+ ):
+ self.vertices = vertices.float()
+ self.faces = faces.int()
+ self.origin = torch.tensor(origin, dtype=torch.float32, device=self.device)
+ self.voxel_size = voxel_size
+ self.coords = coords
+ self.attrs = attrs
+ self.voxel_shape = voxel_shape
+ self.layout = layout
+
+ def to(self, device, non_blocking=False):
+ return MeshWithVoxel(
+ self.vertices.to(device, non_blocking=non_blocking),
+ self.faces.to(device, non_blocking=non_blocking),
+ self.origin.tolist(),
+ self.voxel_size,
+ self.coords.to(device, non_blocking=non_blocking),
+ self.attrs.to(device, non_blocking=non_blocking),
+ self.voxel_shape,
+ self.layout,
+ )
+
+ def query_attrs(self, xyz):
+ grid = ((xyz - self.origin) / self.voxel_size).reshape(1, -1, 3)
+ vertex_attrs = grid_sample_3d(
+ self.attrs,
+ torch.cat([torch.zeros_like(self.coords[..., :1]), self.coords], dim=-1),
+ self.voxel_shape,
+ grid,
+ mode='trilinear'
+ )[0]
+ return vertex_attrs
+
+ def query_vertex_attrs(self):
+ return self.query_attrs(self.vertices)
diff --git a/TRELLIS.2/trellis2/representations/voxel/__init__.py b/TRELLIS.2/trellis2/representations/voxel/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5792ea14b2371a96c4130371eb976f0aff4b5dd
--- /dev/null
+++ b/TRELLIS.2/trellis2/representations/voxel/__init__.py
@@ -0,0 +1 @@
+from .voxel_model import Voxel
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/representations/voxel/voxel_model.py b/TRELLIS.2/trellis2/representations/voxel/voxel_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..9317ab22db61c5da96514ca46a780378392f3cc8
--- /dev/null
+++ b/TRELLIS.2/trellis2/representations/voxel/voxel_model.py
@@ -0,0 +1,54 @@
+from typing import Dict
+import torch
+
+
+class Voxel:
+ def __init__(
+ self,
+ origin: list,
+ voxel_size: float,
+ coords: torch.Tensor = None,
+ attrs: torch.Tensor = None,
+ layout: Dict = {},
+ device: torch.device = 'cuda'
+ ):
+ self.origin = torch.tensor(origin, dtype=torch.float32, device=device)
+ self.voxel_size = voxel_size
+ self.coords = coords
+ self.attrs = attrs
+ self.layout = layout
+ self.device = device
+
+ @property
+ def position(self):
+ return (self.coords + 0.5) * self.voxel_size + self.origin[None, :]
+
+ def split_attrs(self):
+ return {
+ k: self.attrs[:, self.layout[k]]
+ for k in self.layout
+ }
+
+ def save(self, path):
+ # lazy import
+ if 'o_voxel' not in globals():
+ import o_voxel
+ o_voxel.io.write(
+ path,
+ self.coords,
+ self.split_attrs(),
+ )
+
+ def load(self, path):
+ # lazy import
+ if 'o_voxel' not in globals():
+ import o_voxel
+ coord, attrs = o_voxel.io.read(path)
+ self.coords = coord.int().to(self.device)
+ self.attrs = torch.cat([attrs[k] for k in attrs], dim=1).to(self.device)
+ # build layout
+ start = 0
+ self.layout = {}
+ for k in attrs:
+ self.layout[k] = slice(start, start + attrs[k].shape[1])
+ start += attrs[k].shape[1]
diff --git a/TRELLIS.2/trellis2/utils/__init__.py b/TRELLIS.2/trellis2/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/TRELLIS.2/trellis2/utils/data_utils.py b/TRELLIS.2/trellis2/utils/data_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..805b6cc118106857e7ef767ab4bfd133dbd78e6f
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/data_utils.py
@@ -0,0 +1,226 @@
+from typing import *
+import math
+import torch
+import numpy as np
+from torch.utils.data import Sampler, Dataset, DataLoader, DistributedSampler
+import torch.distributed as dist
+
+
+def recursive_to_device(
+ data: Any,
+ device: torch.device,
+ non_blocking: bool = False,
+) -> Any:
+ """
+ Recursively move all tensors in a data structure to a device.
+ """
+ if hasattr(data, "to"):
+ return data.to(device, non_blocking=non_blocking)
+ elif isinstance(data, (list, tuple)):
+ return type(data)(recursive_to_device(d, device, non_blocking) for d in data)
+ elif isinstance(data, dict):
+ return {k: recursive_to_device(v, device, non_blocking) for k, v in data.items()}
+ else:
+ return data
+
+
+def load_balanced_group_indices(
+ load: List[int],
+ num_groups: int,
+ equal_size: bool = False,
+) -> List[List[int]]:
+ """
+ Split indices into groups with balanced load.
+ """
+ if equal_size:
+ group_size = len(load) // num_groups
+ indices = np.argsort(load)[::-1]
+ groups = [[] for _ in range(num_groups)]
+ group_load = np.zeros(num_groups)
+ for idx in indices:
+ min_group_idx = np.argmin(group_load)
+ groups[min_group_idx].append(idx)
+ if equal_size and len(groups[min_group_idx]) == group_size:
+ group_load[min_group_idx] = float('inf')
+ else:
+ group_load[min_group_idx] += load[idx]
+ return groups
+
+
+def cycle(data_loader: DataLoader) -> Iterator:
+ while True:
+ for data in data_loader:
+ if isinstance(data_loader.sampler, ResumableSampler):
+ data_loader.sampler.idx += data_loader.batch_size # type: ignore[attr-defined]
+ yield data
+ if isinstance(data_loader.sampler, DistributedSampler):
+ data_loader.sampler.epoch += 1
+ if isinstance(data_loader.sampler, ResumableSampler):
+ data_loader.sampler.epoch += 1
+ data_loader.sampler.idx = 0
+
+
+class ResumableSampler(Sampler):
+ """
+ Distributed sampler that is resumable.
+
+ Args:
+ dataset: Dataset used for sampling.
+ rank (int, optional): Rank of the current process within :attr:`num_replicas`.
+ By default, :attr:`rank` is retrieved from the current distributed
+ group.
+ shuffle (bool, optional): If ``True`` (default), sampler will shuffle the
+ indices.
+ seed (int, optional): random seed used to shuffle the sampler if
+ :attr:`shuffle=True`. This number should be identical across all
+ processes in the distributed group. Default: ``0``.
+ drop_last (bool, optional): if ``True``, then the sampler will drop the
+ tail of the data to make it evenly divisible across the number of
+ replicas. If ``False``, the sampler will add extra indices to make
+ the data evenly divisible across the replicas. Default: ``False``.
+ """
+
+ def __init__(
+ self,
+ dataset: Dataset,
+ shuffle: bool = True,
+ seed: int = 0,
+ drop_last: bool = False,
+ ) -> None:
+ self.dataset = dataset
+ self.epoch = 0
+ self.idx = 0
+ self.drop_last = drop_last
+ self.world_size = dist.get_world_size() if dist.is_initialized() else 1
+ self.rank = dist.get_rank() if dist.is_initialized() else 0
+ # If the dataset length is evenly divisible by # of replicas, then there
+ # is no need to drop any data, since the dataset will be split equally.
+ if self.drop_last and len(self.dataset) % self.world_size != 0: # type: ignore[arg-type]
+ # Split to nearest available length that is evenly divisible.
+ # This is to ensure each rank receives the same amount of data when
+ # using this Sampler.
+ self.num_samples = math.ceil(
+ (len(self.dataset) - self.world_size) / self.world_size # type: ignore[arg-type]
+ )
+ else:
+ self.num_samples = math.ceil(len(self.dataset) / self.world_size) # type: ignore[arg-type]
+ self.total_size = self.num_samples * self.world_size
+ self.shuffle = shuffle
+ self.seed = seed
+
+ def __iter__(self) -> Iterator:
+ if self.shuffle:
+ # deterministically shuffle based on epoch and seed
+ g = torch.Generator()
+ g.manual_seed(self.seed + self.epoch)
+ indices = torch.randperm(len(self.dataset), generator=g).tolist() # type: ignore[arg-type]
+ else:
+ indices = list(range(len(self.dataset))) # type: ignore[arg-type]
+
+ if not self.drop_last:
+ # add extra samples to make it evenly divisible
+ padding_size = self.total_size - len(indices)
+ if padding_size <= len(indices):
+ indices += indices[:padding_size]
+ else:
+ indices += (indices * math.ceil(padding_size / len(indices)))[
+ :padding_size
+ ]
+ else:
+ # remove tail of data to make it evenly divisible.
+ indices = indices[: self.total_size]
+ assert len(indices) == self.total_size
+
+ # subsample
+ indices = indices[self.rank : self.total_size : self.world_size]
+
+ # resume from previous state
+ indices = indices[self.idx:]
+
+ return iter(indices)
+
+ def __len__(self) -> int:
+ return self.num_samples
+
+ def state_dict(self) -> dict[str, int]:
+ return {
+ 'epoch': self.epoch,
+ 'idx': self.idx,
+ }
+
+ def load_state_dict(self, state_dict):
+ self.epoch = state_dict['epoch']
+ self.idx = state_dict['idx']
+
+
+class BalancedResumableSampler(ResumableSampler):
+ """
+ Distributed sampler that is resumable and balances the load among the processes.
+
+ Args:
+ dataset: Dataset used for sampling.
+ rank (int, optional): Rank of the current process within :attr:`num_replicas`.
+ By default, :attr:`rank` is retrieved from the current distributed
+ group.
+ shuffle (bool, optional): If ``True`` (default), sampler will shuffle the
+ indices.
+ seed (int, optional): random seed used to shuffle the sampler if
+ :attr:`shuffle=True`. This number should be identical across all
+ processes in the distributed group. Default: ``0``.
+ drop_last (bool, optional): if ``True``, then the sampler will drop the
+ tail of the data to make it evenly divisible across the number of
+ replicas. If ``False``, the sampler will add extra indices to make
+ the data evenly divisible across the replicas. Default: ``False``.
+ """
+
+ def __init__(
+ self,
+ dataset: Dataset,
+ shuffle: bool = True,
+ seed: int = 0,
+ drop_last: bool = False,
+ batch_size: int = 1,
+ ) -> None:
+ assert hasattr(dataset, 'loads'), 'Dataset must have "loads" attribute to use BalancedResumableSampler'
+ super().__init__(dataset, shuffle, seed, drop_last)
+ self.batch_size = batch_size
+ self.loads = dataset.loads
+
+ def __iter__(self) -> Iterator:
+ if self.shuffle:
+ # deterministically shuffle based on epoch and seed
+ g = torch.Generator()
+ g.manual_seed(self.seed + self.epoch)
+ indices = torch.randperm(len(self.dataset), generator=g).tolist() # type: ignore[arg-type]
+ else:
+ indices = list(range(len(self.dataset))) # type: ignore[arg-type]
+
+ if not self.drop_last:
+ # add extra samples to make it evenly divisible
+ padding_size = self.total_size - len(indices)
+ if padding_size <= len(indices):
+ indices += indices[:padding_size]
+ else:
+ indices += (indices * math.ceil(padding_size / len(indices)))[
+ :padding_size
+ ]
+ else:
+ # remove tail of data to make it evenly divisible.
+ indices = indices[: self.total_size]
+ assert len(indices) == self.total_size
+
+ # balance load among processes
+ num_batches = len(indices) // (self.batch_size * self.world_size)
+ balanced_indices = []
+ for i in range(num_batches):
+ start_idx = i * self.batch_size * self.world_size
+ end_idx = (i + 1) * self.batch_size * self.world_size
+ batch_indices = indices[start_idx:end_idx]
+ batch_loads = [self.loads[idx] for idx in batch_indices]
+ groups = load_balanced_group_indices(batch_loads, self.world_size, equal_size=True)
+ balanced_indices.extend([batch_indices[j] for j in groups[self.rank]])
+
+ # resume from previous state
+ indices = balanced_indices[self.idx:]
+
+ return iter(indices)
diff --git a/TRELLIS.2/trellis2/utils/dist_utils.py b/TRELLIS.2/trellis2/utils/dist_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..348799c064804ed3ae1a98144249bd9b6bfb9915
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/dist_utils.py
@@ -0,0 +1,93 @@
+import os
+import io
+from contextlib import contextmanager
+import torch
+import torch.distributed as dist
+from torch.nn.parallel import DistributedDataParallel as DDP
+
+
+def setup_dist(rank, local_rank, world_size, master_addr, master_port):
+ os.environ['MASTER_ADDR'] = master_addr
+ os.environ['MASTER_PORT'] = master_port
+ os.environ['WORLD_SIZE'] = str(world_size)
+ os.environ['RANK'] = str(rank)
+ os.environ['LOCAL_RANK'] = str(local_rank)
+ torch.cuda.set_device(local_rank)
+ dist.init_process_group('nccl', rank=rank, world_size=world_size)
+
+
+def read_file_dist(path):
+ """
+ Read the binary file distributedly.
+ File is only read once by the rank 0 process and broadcasted to other processes.
+
+ Returns:
+ data (io.BytesIO): The binary data read from the file.
+ """
+ if dist.is_initialized() and dist.get_world_size() > 1:
+ # read file
+ size = torch.LongTensor(1).cuda()
+ if dist.get_rank() == 0:
+ with open(path, 'rb') as f:
+ data = f.read()
+ data = torch.ByteTensor(
+ torch.UntypedStorage.from_buffer(data, dtype=torch.uint8)
+ ).cuda()
+ size[0] = data.shape[0]
+ # broadcast size
+ dist.broadcast(size, src=0)
+ if dist.get_rank() != 0:
+ data = torch.ByteTensor(size[0].item()).cuda()
+ # broadcast data
+ dist.broadcast(data, src=0)
+ # convert to io.BytesIO
+ data = data.cpu().numpy().tobytes()
+ data = io.BytesIO(data)
+ return data
+ else:
+ with open(path, 'rb') as f:
+ data = f.read()
+ data = io.BytesIO(data)
+ return data
+
+
+def unwrap_dist(model):
+ """
+ Unwrap the model from distributed training.
+ """
+ if isinstance(model, DDP):
+ return model.module
+ return model
+
+
+@contextmanager
+def master_first():
+ """
+ A context manager that ensures master process executes first.
+ """
+ if not dist.is_initialized():
+ yield
+ else:
+ if dist.get_rank() == 0:
+ yield
+ dist.barrier()
+ else:
+ dist.barrier()
+ yield
+
+
+@contextmanager
+def local_master_first():
+ """
+ A context manager that ensures local master process executes first.
+ """
+ if not dist.is_initialized():
+ yield
+ else:
+ if dist.get_rank() % torch.cuda.device_count() == 0:
+ yield
+ dist.barrier()
+ else:
+ dist.barrier()
+ yield
+
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/utils/elastic_utils.py b/TRELLIS.2/trellis2/utils/elastic_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..cba3cf83836e5b58f5bc3333e809ffc932375a04
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/elastic_utils.py
@@ -0,0 +1,228 @@
+from abc import abstractmethod
+from contextlib import contextmanager
+from typing import Tuple
+import torch
+import torch.nn as nn
+import numpy as np
+
+
+class MemoryController:
+ """
+ Base class for memory management during training.
+ """
+
+ _last_input_size = None
+ _last_mem_ratio = []
+
+ @contextmanager
+ def record(self):
+ pass
+
+ def update_run_states(self, input_size=None, mem_ratio=None):
+ if self._last_input_size is None:
+ self._last_input_size = input_size
+ elif self._last_input_size!= input_size:
+ raise ValueError(f'Input size should not change for different ElasticModules.')
+ self._last_mem_ratio.append(mem_ratio)
+
+ @abstractmethod
+ def get_mem_ratio(self, input_size):
+ pass
+
+ @abstractmethod
+ def state_dict(self):
+ pass
+
+ @abstractmethod
+ def log(self):
+ pass
+
+
+class LinearMemoryController(MemoryController):
+ """
+ A simple controller for memory management during training.
+ The memory usage is modeled as a linear function of:
+ - the number of input parameters
+ - the ratio of memory the model use compared to the maximum usage (with no checkpointing)
+ memory_usage = k * input_size * mem_ratio + b
+ The controller keeps track of the memory usage and gives the
+ expected memory ratio to keep the memory usage under a target
+ """
+ def __init__(
+ self,
+ buffer_size=1000,
+ update_every=500,
+ target_ratio=0.8,
+ available_memory=None,
+ max_mem_ratio_start=0.1,
+ params=None,
+ device=None
+ ):
+ self.buffer_size = buffer_size
+ self.update_every = update_every
+ self.target_ratio = target_ratio
+ self.device = device or torch.cuda.current_device()
+ self.available_memory = available_memory or torch.cuda.get_device_properties(self.device).total_memory / 1024**3
+
+ self._memory = np.zeros(buffer_size, dtype=np.float32)
+ self._input_size = np.zeros(buffer_size, dtype=np.float32)
+ self._mem_ratio = np.zeros(buffer_size, dtype=np.float32)
+ self._buffer_ptr = 0
+ self._buffer_length = 0
+ self._params = tuple(params) if params is not None else (0.0, 0.0)
+ self._max_mem_ratio = max_mem_ratio_start
+ self.step = 0
+
+ def __repr__(self):
+ return f'LinearMemoryController(target_ratio={self.target_ratio}, available_memory={self.available_memory})'
+
+ def _add_sample(self, memory, input_size, mem_ratio):
+ self._memory[self._buffer_ptr] = memory
+ self._input_size[self._buffer_ptr] = input_size
+ self._mem_ratio[self._buffer_ptr] = mem_ratio
+ self._buffer_ptr = (self._buffer_ptr + 1) % self.buffer_size
+ self._buffer_length = min(self._buffer_length + 1, self.buffer_size)
+
+ @contextmanager
+ def record(self):
+ torch.cuda.reset_peak_memory_stats(self.device)
+ self._last_input_size = None
+ self._last_mem_ratio = []
+ yield
+ self._last_memory = torch.cuda.max_memory_allocated(self.device) / 1024**3
+ self._last_mem_ratio = sum(self._last_mem_ratio) / len(self._last_mem_ratio)
+ self._add_sample(self._last_memory, self._last_input_size, self._last_mem_ratio)
+ self.step += 1
+ if self.step % self.update_every == 0:
+ self._max_mem_ratio = min(1.0, self._max_mem_ratio + 0.1)
+ self._fit_params()
+
+ def _fit_params(self):
+ memory_usage = self._memory[:self._buffer_length]
+ input_size = self._input_size[:self._buffer_length]
+ mem_ratio = self._mem_ratio[:self._buffer_length]
+
+ x = input_size * mem_ratio
+ y = memory_usage
+ k, b = np.polyfit(x, y, 1)
+ self._params = (k, b)
+ # self._visualize()
+
+ def _visualize(self):
+ import matplotlib.pyplot as plt
+ memory_usage = self._memory[:self._buffer_length]
+ input_size = self._input_size[:self._buffer_length]
+ mem_ratio = self._mem_ratio[:self._buffer_length]
+ k, b = self._params
+
+ plt.scatter(input_size * mem_ratio, memory_usage, c=mem_ratio, cmap='viridis')
+ x = np.array([0.0, 20000.0])
+ plt.plot(x, k * x + b, c='r')
+ plt.savefig(f'linear_memory_controller_{self.step}.png')
+ plt.cla()
+
+ def get_mem_ratio(self, input_size):
+ k, b = self._params
+ if k == 0: return np.random.rand() * self._max_mem_ratio
+ pred = (self.available_memory * self.target_ratio - b) / (k * input_size)
+ return min(self._max_mem_ratio, max(0.0, pred))
+
+ def state_dict(self):
+ return {
+ 'params': self._params,
+ }
+
+ def load_state_dict(self, state_dict):
+ self._params = tuple(state_dict['params'])
+
+ def log(self):
+ return {
+ 'params/k': self._params[0],
+ 'params/b': self._params[1],
+ 'memory': self._last_memory,
+ 'input_size': self._last_input_size,
+ 'mem_ratio': self._last_mem_ratio,
+ }
+
+
+class ElasticModule(nn.Module):
+ """
+ Module for training with elastic memory management.
+ """
+ def __init__(self):
+ super().__init__()
+ self._memory_controller: MemoryController = None
+
+ @abstractmethod
+ def _get_input_size(self, *args, **kwargs) -> int:
+ """
+ Get the size of the input data.
+
+ Returns:
+ int: The size of the input data.
+ """
+ pass
+
+ @abstractmethod
+ def _forward_with_mem_ratio(self, *args, mem_ratio=0.0, **kwargs) -> Tuple[float, Tuple]:
+ """
+ Forward with a given memory ratio.
+ """
+ pass
+
+ def register_memory_controller(self, memory_controller: MemoryController):
+ self._memory_controller = memory_controller
+
+ def forward(self, *args, **kwargs):
+ if self._memory_controller is None or not torch.is_grad_enabled() or not self.training:
+ _, ret = self._forward_with_mem_ratio(*args, **kwargs)
+ else:
+ input_size = self._get_input_size(*args, **kwargs)
+ mem_ratio = self._memory_controller.get_mem_ratio(input_size)
+ mem_ratio, ret = self._forward_with_mem_ratio(*args, mem_ratio=mem_ratio, **kwargs)
+ self._memory_controller.update_run_states(input_size, mem_ratio)
+ return ret
+
+
+class ElasticModuleMixin:
+ """
+ Mixin for training with elastic memory management.
+ """
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self._memory_controller: MemoryController = None
+
+ @abstractmethod
+ def _get_input_size(self, *args, **kwargs) -> int:
+ """
+ Get the size of the input data.
+
+ Returns:
+ int: The size of the input data.
+ """
+ pass
+
+ @abstractmethod
+ @contextmanager
+ def with_mem_ratio(self, mem_ratio=1.0) -> float:
+ """
+ Context manager for training with a reduced memory ratio compared to the full memory usage.
+
+ Returns:
+ float: The exact memory ratio used during the forward pass.
+ """
+ pass
+
+ def register_memory_controller(self, memory_controller: MemoryController):
+ self._memory_controller = memory_controller
+
+ def forward(self, *args, **kwargs):
+ if self._memory_controller is None or not torch.is_grad_enabled() or not self.training:
+ ret = super().forward(*args, **kwargs)
+ else:
+ input_size = self._get_input_size(*args, **kwargs)
+ mem_ratio = self._memory_controller.get_mem_ratio(input_size)
+ with self.with_mem_ratio(mem_ratio) as exact_mem_ratio:
+ ret = super().forward(*args, **kwargs)
+ self._memory_controller.update_run_states(input_size, exact_mem_ratio)
+ return ret
diff --git a/TRELLIS.2/trellis2/utils/general_utils.py b/TRELLIS.2/trellis2/utils/general_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..589c103de8a777aea9994a899f97431cbab5447a
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/general_utils.py
@@ -0,0 +1,373 @@
+import re
+import numpy as np
+import cv2
+import torch
+import contextlib
+
+
+# Dictionary utils
+def _dict_merge(dicta, dictb, prefix=''):
+ """
+ Merge two dictionaries.
+ """
+ assert isinstance(dicta, dict), 'input must be a dictionary'
+ assert isinstance(dictb, dict), 'input must be a dictionary'
+ dict_ = {}
+ all_keys = set(dicta.keys()).union(set(dictb.keys()))
+ for key in all_keys:
+ if key in dicta.keys() and key in dictb.keys():
+ if isinstance(dicta[key], dict) and isinstance(dictb[key], dict):
+ dict_[key] = _dict_merge(dicta[key], dictb[key], prefix=f'{prefix}.{key}')
+ else:
+ raise ValueError(f'Duplicate key {prefix}.{key} found in both dictionaries. Types: {type(dicta[key])}, {type(dictb[key])}')
+ elif key in dicta.keys():
+ dict_[key] = dicta[key]
+ else:
+ dict_[key] = dictb[key]
+ return dict_
+
+
+def dict_merge(dicta, dictb):
+ """
+ Merge two dictionaries.
+ """
+ return _dict_merge(dicta, dictb, prefix='')
+
+
+def dict_foreach(dic, func, special_func={}):
+ """
+ Recursively apply a function to all non-dictionary leaf values in a dictionary.
+ """
+ assert isinstance(dic, dict), 'input must be a dictionary'
+ for key in dic.keys():
+ if isinstance(dic[key], dict):
+ dic[key] = dict_foreach(dic[key], func)
+ else:
+ if key in special_func.keys():
+ dic[key] = special_func[key](dic[key])
+ else:
+ dic[key] = func(dic[key])
+ return dic
+
+
+def dict_reduce(dicts, func, special_func={}):
+ """
+ Reduce a list of dictionaries. Leaf values must be scalars.
+ """
+ assert isinstance(dicts, list), 'input must be a list of dictionaries'
+ assert all([isinstance(d, dict) for d in dicts]), 'input must be a list of dictionaries'
+ assert len(dicts) > 0, 'input must be a non-empty list of dictionaries'
+ all_keys = set([key for dict_ in dicts for key in dict_.keys()])
+ reduced_dict = {}
+ for key in all_keys:
+ vlist = [dict_[key] for dict_ in dicts if key in dict_.keys()]
+ if isinstance(vlist[0], dict):
+ reduced_dict[key] = dict_reduce(vlist, func, special_func)
+ else:
+ if key in special_func.keys():
+ reduced_dict[key] = special_func[key](vlist)
+ else:
+ reduced_dict[key] = func(vlist)
+ return reduced_dict
+
+
+def dict_any(dic, func):
+ """
+ Recursively apply a function to all non-dictionary leaf values in a dictionary.
+ """
+ assert isinstance(dic, dict), 'input must be a dictionary'
+ for key in dic.keys():
+ if isinstance(dic[key], dict):
+ if dict_any(dic[key], func):
+ return True
+ else:
+ if func(dic[key]):
+ return True
+ return False
+
+
+def dict_all(dic, func):
+ """
+ Recursively apply a function to all non-dictionary leaf values in a dictionary.
+ """
+ assert isinstance(dic, dict), 'input must be a dictionary'
+ for key in dic.keys():
+ if isinstance(dic[key], dict):
+ if not dict_all(dic[key], func):
+ return False
+ else:
+ if not func(dic[key]):
+ return False
+ return True
+
+
+def dict_flatten(dic, sep='.'):
+ """
+ Flatten a nested dictionary into a dictionary with no nested dictionaries.
+ """
+ assert isinstance(dic, dict), 'input must be a dictionary'
+ flat_dict = {}
+ for key in dic.keys():
+ if isinstance(dic[key], dict):
+ sub_dict = dict_flatten(dic[key], sep=sep)
+ for sub_key in sub_dict.keys():
+ flat_dict[str(key) + sep + str(sub_key)] = sub_dict[sub_key]
+ else:
+ flat_dict[key] = dic[key]
+ return flat_dict
+
+
+# Context utils
+@contextlib.contextmanager
+def nested_contexts(*contexts):
+ with contextlib.ExitStack() as stack:
+ for ctx in contexts:
+ stack.enter_context(ctx())
+ yield
+
+
+# Image utils
+def make_grid(images, nrow=None, ncol=None, aspect_ratio=None):
+ num_images = len(images)
+ if nrow is None and ncol is None:
+ if aspect_ratio is not None:
+ nrow = int(np.round(np.sqrt(num_images / aspect_ratio)))
+ else:
+ nrow = int(np.sqrt(num_images))
+ ncol = (num_images + nrow - 1) // nrow
+ elif nrow is None and ncol is not None:
+ nrow = (num_images + ncol - 1) // ncol
+ elif nrow is not None and ncol is None:
+ ncol = (num_images + nrow - 1) // nrow
+ else:
+ assert nrow * ncol >= num_images, 'nrow * ncol must be greater than or equal to the number of images'
+
+ if images[0].ndim == 2:
+ grid = np.zeros((nrow * images[0].shape[0], ncol * images[0].shape[1]), dtype=images[0].dtype)
+ else:
+ grid = np.zeros((nrow * images[0].shape[0], ncol * images[0].shape[1], images[0].shape[2]), dtype=images[0].dtype)
+ for i, img in enumerate(images):
+ row = i // ncol
+ col = i % ncol
+ grid[row * img.shape[0]:(row + 1) * img.shape[0], col * img.shape[1]:(col + 1) * img.shape[1]] = img
+ return grid
+
+
+def notes_on_image(img, notes=None):
+ img = np.pad(img, ((0, 32), (0, 0), (0, 0)), 'constant', constant_values=0)
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
+ if notes is not None:
+ img = cv2.putText(img, notes, (0, img.shape[0] - 4), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1)
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
+ return img
+
+
+
+def text_image(text, resolution=(512, 512), max_size=0.5, h_align="left", v_align="center"):
+ """
+ Draw text on an image of the given resolution. The text is automatically wrapped
+ and scaled so that it fits completely within the image while preserving any explicit
+ line breaks and original spacing. Horizontal and vertical alignment can be controlled
+ via flags.
+
+ Parameters:
+ text (str): The input text. Newline characters and spacing are preserved.
+ resolution (tuple): The image resolution as (width, height).
+ max_size (float): The maximum font size.
+ h_align (str): Horizontal alignment. Options: "left", "center", "right".
+ v_align (str): Vertical alignment. Options: "top", "center", "bottom".
+
+ Returns:
+ numpy.ndarray: The resulting image (BGR format) with the text drawn.
+ """
+ width, height = resolution
+ # Create a white background image
+ img = np.full((height, width, 3), 255, dtype=np.uint8)
+
+ # Set margins and compute available drawing area
+ margin = 10
+ avail_width = width - 2 * margin
+ avail_height = height - 2 * margin
+
+ # Choose OpenCV font and text thickness
+ font = cv2.FONT_HERSHEY_SIMPLEX
+ thickness = 1
+ # Ratio for additional spacing between lines (relative to the height of "A")
+ line_spacing_ratio = 0.5
+
+ def wrap_line(line, max_width, font, thickness, scale):
+ """
+ Wrap a single line of text into multiple lines such that each line's
+ width (measured at the given scale) does not exceed max_width.
+ This function preserves the original spacing by splitting the line into tokens
+ (words and whitespace) using a regular expression.
+
+ Parameters:
+ line (str): The input text line.
+ max_width (int): Maximum allowed width in pixels.
+ font (int): OpenCV font identifier.
+ thickness (int): Text thickness.
+ scale (float): The current font scale.
+
+ Returns:
+ List[str]: A list of wrapped lines.
+ """
+ # Split the line into tokens (words and whitespace), preserving spacing
+ tokens = re.split(r'(\s+)', line)
+ if not tokens:
+ return ['']
+
+ wrapped_lines = []
+ current_line = ""
+ for token in tokens:
+ candidate = current_line + token
+ candidate_width = cv2.getTextSize(candidate, font, scale, thickness)[0][0]
+ if candidate_width <= max_width:
+ current_line = candidate
+ else:
+ # If current_line is empty, the token itself is too wide;
+ # break the token character by character.
+ if current_line == "":
+ sub_token = ""
+ for char in token:
+ candidate_char = sub_token + char
+ if cv2.getTextSize(candidate_char, font, scale, thickness)[0][0] <= max_width:
+ sub_token = candidate_char
+ else:
+ if sub_token:
+ wrapped_lines.append(sub_token)
+ sub_token = char
+ current_line = sub_token
+ else:
+ wrapped_lines.append(current_line)
+ current_line = token
+ if current_line:
+ wrapped_lines.append(current_line)
+ return wrapped_lines
+
+ def compute_text_block(scale):
+ """
+ Wrap the entire text (splitting at explicit newline characters) using the
+ provided scale, and then compute the overall width and height of the text block.
+
+ Returns:
+ wrapped_lines (List[str]): The list of wrapped lines.
+ block_width (int): Maximum width among the wrapped lines.
+ block_height (int): Total height of the text block including spacing.
+ sizes (List[tuple]): A list of (width, height) for each wrapped line.
+ spacing (int): The spacing between lines (computed from the scaled "A" height).
+ """
+ # Split text by explicit newlines
+ input_lines = text.splitlines() if text else ['']
+ wrapped_lines = []
+ for line in input_lines:
+ wrapped = wrap_line(line, avail_width, font, thickness, scale)
+ wrapped_lines.extend(wrapped)
+
+ sizes = []
+ for line in wrapped_lines:
+ (text_size, _) = cv2.getTextSize(line, font, scale, thickness)
+ sizes.append(text_size) # (width, height)
+
+ block_width = max((w for w, h in sizes), default=0)
+ # Use the height of "A" (at the current scale) to compute line spacing
+ base_height = cv2.getTextSize("A", font, scale, thickness)[0][1]
+ spacing = int(line_spacing_ratio * base_height)
+ block_height = sum(h for w, h in sizes) + spacing * (len(sizes) - 1) if sizes else 0
+
+ return wrapped_lines, block_width, block_height, sizes, spacing
+
+ # Use binary search to find the maximum scale that allows the text block to fit
+ lo = 0.001
+ hi = max_size
+ eps = 0.001 # convergence threshold
+ best_scale = lo
+ best_result = None
+
+ while hi - lo > eps:
+ mid = (lo + hi) / 2
+ wrapped_lines, block_width, block_height, sizes, spacing = compute_text_block(mid)
+ # Ensure that both width and height constraints are met
+ if block_width <= avail_width and block_height <= avail_height:
+ best_scale = mid
+ best_result = (wrapped_lines, block_width, block_height, sizes, spacing)
+ lo = mid # try a larger scale
+ else:
+ hi = mid # reduce the scale
+
+ if best_result is None:
+ best_scale = 0.5
+ best_result = compute_text_block(best_scale)
+
+ wrapped_lines, block_width, block_height, sizes, spacing = best_result
+
+ # Compute starting y-coordinate based on vertical alignment flag
+ if v_align == "top":
+ y_top = margin
+ elif v_align == "center":
+ y_top = margin + (avail_height - block_height) // 2
+ elif v_align == "bottom":
+ y_top = margin + (avail_height - block_height)
+ else:
+ y_top = margin + (avail_height - block_height) // 2 # default to center if invalid flag
+
+ # For cv2.putText, the y coordinate represents the text baseline;
+ # so for the first line add its height.
+ y = y_top + (sizes[0][1] if sizes else 0)
+
+ # Draw each line with horizontal alignment based on the flag
+ for i, line in enumerate(wrapped_lines):
+ line_width, line_height = sizes[i]
+ if h_align == "left":
+ x = margin
+ elif h_align == "center":
+ x = margin + (avail_width - line_width) // 2
+ elif h_align == "right":
+ x = margin + (avail_width - line_width)
+ else:
+ x = margin # default to left if invalid flag
+
+ cv2.putText(img, line, (x, y), font, best_scale, (0, 0, 0), thickness, cv2.LINE_AA)
+ y += line_height + spacing
+
+ return img
+
+
+def save_image_with_notes(img, path, notes=None):
+ """
+ Save an image with notes.
+ """
+ if isinstance(img, torch.Tensor):
+ img = img.cpu().numpy().transpose(1, 2, 0)
+ if img.dtype == np.float32 or img.dtype == np.float64:
+ img = np.clip(img * 255, 0, 255).astype(np.uint8)
+ img = notes_on_image(img, notes)
+ cv2.imwrite(path, cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
+
+
+# debug utils
+
+def atol(x, y):
+ """
+ Absolute tolerance.
+ """
+ return torch.abs(x - y)
+
+
+def rtol(x, y):
+ """
+ Relative tolerance.
+ """
+ return torch.abs(x - y) / torch.clamp_min(torch.maximum(torch.abs(x), torch.abs(y)), 1e-12)
+
+
+# print utils
+def indent(s, n=4):
+ """
+ Indent a string.
+ """
+ lines = s.split('\n')
+ for i in range(1, len(lines)):
+ lines[i] = ' ' * n + lines[i]
+ return '\n'.join(lines)
+
diff --git a/TRELLIS.2/trellis2/utils/grad_clip_utils.py b/TRELLIS.2/trellis2/utils/grad_clip_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..990a4352e24fc73bf732d8eb0f8ca9a07365b49e
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/grad_clip_utils.py
@@ -0,0 +1,81 @@
+from typing import *
+import torch
+import numpy as np
+import torch.utils
+
+
+class AdaptiveGradClipper:
+ """
+ Adaptive gradient clipping for training.
+ """
+ def __init__(
+ self,
+ max_norm=None,
+ clip_percentile=95.0,
+ buffer_size=1000,
+ ):
+ self.max_norm = max_norm
+ self.clip_percentile = clip_percentile
+ self.buffer_size = buffer_size
+
+ self._grad_norm = np.zeros(buffer_size, dtype=np.float32)
+ self._max_norm = max_norm
+ self._buffer_ptr = 0
+ self._buffer_length = 0
+
+ def __repr__(self):
+ return f'AdaptiveGradClipper(max_norm={self.max_norm}, clip_percentile={self.clip_percentile})'
+
+ def state_dict(self):
+ return {
+ 'grad_norm': self._grad_norm,
+ 'max_norm': self._max_norm,
+ 'buffer_ptr': self._buffer_ptr,
+ 'buffer_length': self._buffer_length,
+ }
+
+ def load_state_dict(self, state_dict):
+ self._grad_norm = state_dict['grad_norm']
+ self._max_norm = state_dict['max_norm']
+ self._buffer_ptr = state_dict['buffer_ptr']
+ self._buffer_length = state_dict['buffer_length']
+
+ def log(self):
+ return {
+ 'max_norm': self._max_norm,
+ }
+
+ def __call__(self, parameters, norm_type=2.0, error_if_nonfinite=False, foreach=None):
+ """Clip the gradient norm of an iterable of parameters.
+
+ The norm is computed over all gradients together, as if they were
+ concatenated into a single vector. Gradients are modified in-place.
+
+ Args:
+ parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a
+ single Tensor that will have gradients normalized
+ norm_type (float): type of the used p-norm. Can be ``'inf'`` for
+ infinity norm.
+ error_if_nonfinite (bool): if True, an error is thrown if the total
+ norm of the gradients from :attr:`parameters` is ``nan``,
+ ``inf``, or ``-inf``. Default: False (will switch to True in the future)
+ foreach (bool): use the faster foreach-based implementation.
+ If ``None``, use the foreach implementation for CUDA and CPU native tensors and silently
+ fall back to the slow implementation for other device types.
+ Default: ``None``
+
+ Returns:
+ Total norm of the parameter gradients (viewed as a single vector).
+ """
+ max_norm = self._max_norm if self._max_norm is not None else float('inf')
+ grad_norm = torch.nn.utils.clip_grad_norm_(parameters, max_norm=max_norm, norm_type=norm_type, error_if_nonfinite=error_if_nonfinite, foreach=foreach)
+
+ if torch.isfinite(grad_norm):
+ self._grad_norm[self._buffer_ptr] = grad_norm
+ self._buffer_ptr = (self._buffer_ptr + 1) % self.buffer_size
+ self._buffer_length = min(self._buffer_length + 1, self.buffer_size)
+ if self._buffer_length == self.buffer_size:
+ self._max_norm = np.percentile(self._grad_norm, self.clip_percentile)
+ self._max_norm = min(self._max_norm, self.max_norm) if self.max_norm is not None else self._max_norm
+
+ return grad_norm
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/utils/loss_utils.py b/TRELLIS.2/trellis2/utils/loss_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..52049f69543f2700bc5525b09cbf2fb25c08aa9e
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/loss_utils.py
@@ -0,0 +1,92 @@
+import torch
+import torch.nn.functional as F
+from torch.autograd import Variable
+from math import exp
+from lpips import LPIPS
+
+
+def smooth_l1_loss(pred, target, beta=1.0):
+ diff = torch.abs(pred - target)
+ loss = torch.where(diff < beta, 0.5 * diff ** 2 / beta, diff - 0.5 * beta)
+ return loss.mean()
+
+
+def l1_loss(network_output, gt):
+ return torch.abs((network_output - gt)).mean()
+
+
+def l2_loss(network_output, gt):
+ return ((network_output - gt) ** 2).mean()
+
+
+def gaussian(window_size, sigma):
+ gauss = torch.Tensor([exp(-(x - window_size // 2) ** 2 / float(2 * sigma ** 2)) for x in range(window_size)])
+ return gauss / gauss.sum()
+
+
+def create_window(window_size, channel):
+ _1D_window = gaussian(window_size, 1.5).unsqueeze(1)
+ _2D_window = _1D_window.mm(_1D_window.t()).float().unsqueeze(0).unsqueeze(0)
+ window = Variable(_2D_window.expand(channel, 1, window_size, window_size).contiguous())
+ return window
+
+
+def psnr(img1, img2, max_val=1.0):
+ mse = F.mse_loss(img1, img2)
+ return 20 * torch.log10(max_val / torch.sqrt(mse))
+
+
+def ssim(img1, img2, window_size=11, size_average=True):
+ channel = img1.size(-3)
+ window = create_window(window_size, channel)
+
+ if img1.is_cuda:
+ window = window.cuda(img1.get_device())
+ window = window.type_as(img1)
+
+ return _ssim(img1, img2, window, window_size, channel, size_average)
+
+def _ssim(img1, img2, window, window_size, channel, size_average=True):
+ mu1 = F.conv2d(img1, window, padding=window_size // 2, groups=channel)
+ mu2 = F.conv2d(img2, window, padding=window_size // 2, groups=channel)
+
+ mu1_sq = mu1.pow(2)
+ mu2_sq = mu2.pow(2)
+ mu1_mu2 = mu1 * mu2
+
+ sigma1_sq = F.conv2d(img1 * img1, window, padding=window_size // 2, groups=channel) - mu1_sq
+ sigma2_sq = F.conv2d(img2 * img2, window, padding=window_size // 2, groups=channel) - mu2_sq
+ sigma12 = F.conv2d(img1 * img2, window, padding=window_size // 2, groups=channel) - mu1_mu2
+
+ C1 = 0.01 ** 2
+ C2 = 0.03 ** 2
+
+ ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2))
+
+ if size_average:
+ return ssim_map.mean()
+ else:
+ return ssim_map.mean(1).mean(1).mean(1)
+
+
+loss_fn_vgg = None
+def lpips(img1, img2, value_range=(0, 1)):
+ global loss_fn_vgg
+ if loss_fn_vgg is None:
+ loss_fn_vgg = LPIPS(net='vgg').cuda().eval()
+ # normalize to [-1, 1]
+ img1 = (img1 - value_range[0]) / (value_range[1] - value_range[0]) * 2 - 1
+ img2 = (img2 - value_range[0]) / (value_range[1] - value_range[0]) * 2 - 1
+ return loss_fn_vgg(img1, img2).mean()
+
+
+def normal_angle(pred, gt):
+ pred = pred * 2.0 - 1.0
+ gt = gt * 2.0 - 1.0
+ norms = pred.norm(dim=-1) * gt.norm(dim=-1)
+ cos_sim = (pred * gt).sum(-1) / (norms + 1e-9)
+ cos_sim = torch.clamp(cos_sim, -1.0, 1.0)
+ ang = torch.rad2deg(torch.acos(cos_sim[norms > 1e-9])).mean()
+ if ang.isnan():
+ return -1
+ return ang
diff --git a/TRELLIS.2/trellis2/utils/mesh_utils.py b/TRELLIS.2/trellis2/utils/mesh_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9f1451ebd8b89879eee79cc61a6f4161136f245
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/mesh_utils.py
@@ -0,0 +1,268 @@
+from typing import Tuple, Dict
+import numpy as np
+from trimesh import grouping, util, remesh
+import struct
+import re
+from plyfile import PlyData, PlyElement
+
+
+def read_ply(filename):
+ """
+ Read a PLY file and return vertices, triangle faces, and quad faces.
+
+ Args:
+ filename (str): The file path to read from.
+
+ Returns:
+ vertices (np.ndarray): Array of shape [N, 3] containing vertex positions.
+ tris (np.ndarray): Array of shape [M, 3] containing triangle face indices (empty if none).
+ quads (np.ndarray): Array of shape [K, 4] containing quad face indices (empty if none).
+ """
+ with open(filename, 'rb') as f:
+ # Read the header until 'end_header' is encountered
+ header_bytes = b""
+ while True:
+ line = f.readline()
+ if not line:
+ raise ValueError("PLY header not found")
+ header_bytes += line
+ if b"end_header" in line:
+ break
+ header = header_bytes.decode('utf-8')
+
+ # Determine if the file is in ASCII or binary format
+ is_ascii = "ascii" in header
+
+ # Extract the number of vertices and faces from the header using regex
+ vertex_match = re.search(r'element vertex (\d+)', header)
+ if vertex_match:
+ num_vertices = int(vertex_match.group(1))
+ else:
+ raise ValueError("Vertex count not found in header")
+
+ face_match = re.search(r'element face (\d+)', header)
+ if face_match:
+ num_faces = int(face_match.group(1))
+ else:
+ raise ValueError("Face count not found in header")
+
+ vertices = []
+ tris = []
+ quads = []
+
+ if is_ascii:
+ # For ASCII format, read each line of vertex data (each line contains 3 floats)
+ for _ in range(num_vertices):
+ line = f.readline().decode('utf-8').strip()
+ if not line:
+ continue
+ parts = line.split()
+ vertices.append([float(parts[0]), float(parts[1]), float(parts[2])])
+
+ # Read face data, where the first number indicates the number of vertices for the face
+ for _ in range(num_faces):
+ line = f.readline().decode('utf-8').strip()
+ if not line:
+ continue
+ parts = line.split()
+ count = int(parts[0])
+ indices = list(map(int, parts[1:]))
+ if count == 3:
+ tris.append(indices)
+ elif count == 4:
+ quads.append(indices)
+ else:
+ # Skip faces with other numbers of vertices (can be extended as needed)
+ pass
+ else:
+ # For binary format: read directly from the binary stream
+ # Each vertex consists of 3 floats (12 bytes per vertex)
+ for _ in range(num_vertices):
+ data = f.read(12)
+ if len(data) < 12:
+ raise ValueError("Insufficient vertex data")
+ v = struct.unpack(' 0 else np.empty((0, 3), dtype=np.int32)
+ quads = np.array(quads, dtype=np.int32) if len(quads) > 0 else np.empty((0, 4), dtype=np.int32)
+
+ return vertices, tris, quads
+
+
+def write_ply(
+ filename: str,
+ vertices: np.ndarray,
+ tris: np.ndarray,
+ quads: np.ndarray,
+ vertex_colors: np.ndarray = None,
+ ascii: bool = False
+):
+ """
+ Write a mesh to a PLY file, with the option to save in ASCII or binary format,
+ and optional per-vertex colors.
+
+ Args:
+ filename (str): The filename to write to.
+ vertices (np.ndarray): [N, 3] The vertex positions.
+ tris (np.ndarray): [M, 3] The triangle indices.
+ quads (np.ndarray): [K, 4] The quad indices.
+ vertex_colors (np.ndarray, optional): [N, 3] or [N, 4] UInt8 colors for each vertex (RGB or RGBA).
+ ascii (bool): If True, write in ASCII format; otherwise binary little-endian.
+ """
+ import struct
+
+ num_vertices = len(vertices)
+ num_faces = len(tris) + len(quads)
+
+ # Build header
+ header_lines = [
+ "ply",
+ f"format {'ascii 1.0' if ascii else 'binary_little_endian 1.0'}",
+ f"element vertex {num_vertices}",
+ "property float x",
+ "property float y",
+ "property float z",
+ ]
+
+ # Add vertex color properties if provided
+ has_color = vertex_colors is not None
+ if has_color:
+ # Expect uint8 values 0-255
+ header_lines += [
+ "property uchar red",
+ "property uchar green",
+ "property uchar blue",
+ ]
+ # Include alpha if RGBA
+ if vertex_colors.shape[1] == 4:
+ header_lines.append("property uchar alpha")
+
+ header_lines += [
+ f"element face {num_faces}",
+ "property list uchar int vertex_index",
+ "end_header",
+ ""
+ ]
+ header = "\n".join(header_lines)
+
+ mode = 'w' if ascii else 'wb'
+ with open(filename, mode) as f:
+ # Write header
+ if ascii:
+ f.write(header)
+ else:
+ f.write(header.encode('utf-8'))
+
+ # Write vertex data
+ for i, v in enumerate(vertices):
+ if ascii:
+ line = f"{v[0]} {v[1]} {v[2]}"
+ if has_color:
+ col = vertex_colors[i]
+ line += ' ' + ' '.join(str(int(c)) for c in col)
+ f.write(line + '\n')
+ else:
+ # pack xyz as floats
+ f.write(struct.pack(' 0:
+ digit = n % base
+ val += digit * inv_base_n
+ n //= base
+ inv_base_n *= inv_base
+ return val
+
+def halton_sequence(dim, n):
+ return [radical_inverse(PRIMES[dim], n) for dim in range(dim)]
+
+def hammersley_sequence(dim, n, num_samples):
+ return [n / num_samples] + halton_sequence(dim - 1, n)
+
+def sphere_hammersley_sequence(n, num_samples, offset=(0, 0), remap=False):
+ u, v = hammersley_sequence(2, n, num_samples)
+ u += offset[0] / num_samples
+ v += offset[1]
+ if remap:
+ u = 2 * u if u < 0.25 else 2 / 3 * u + 1 / 3
+ theta = np.arccos(1 - 2 * u) - np.pi / 2
+ phi = v * 2 * np.pi
+ return [phi, theta]
\ No newline at end of file
diff --git a/TRELLIS.2/trellis2/utils/render_utils.py b/TRELLIS.2/trellis2/utils/render_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..d6fb3e9c3b0d826f77ff56d65ccf4adbc247cf0d
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/render_utils.py
@@ -0,0 +1,129 @@
+import torch
+import numpy as np
+from tqdm import tqdm
+import utils3d
+from PIL import Image
+
+from ..renderers import MeshRenderer, VoxelRenderer, PbrMeshRenderer
+from ..representations import Mesh, Voxel, MeshWithPbrMaterial, MeshWithVoxel
+from .random_utils import sphere_hammersley_sequence
+
+
+def yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, rs, fovs):
+ is_list = isinstance(yaws, list)
+ if not is_list:
+ yaws = [yaws]
+ pitchs = [pitchs]
+ if not isinstance(rs, list):
+ rs = [rs] * len(yaws)
+ if not isinstance(fovs, list):
+ fovs = [fovs] * len(yaws)
+ extrinsics = []
+ intrinsics = []
+ for yaw, pitch, r, fov in zip(yaws, pitchs, rs, fovs):
+ fov = torch.deg2rad(torch.tensor(float(fov))).cuda()
+ yaw = torch.tensor(float(yaw)).cuda()
+ pitch = torch.tensor(float(pitch)).cuda()
+ orig = torch.tensor([
+ torch.sin(yaw) * torch.cos(pitch),
+ torch.cos(yaw) * torch.cos(pitch),
+ torch.sin(pitch),
+ ]).cuda() * r
+ extr = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda())
+ intr = utils3d.torch.intrinsics_from_fov_xy(fov, fov)
+ extrinsics.append(extr)
+ intrinsics.append(intr)
+ if not is_list:
+ extrinsics = extrinsics[0]
+ intrinsics = intrinsics[0]
+ return extrinsics, intrinsics
+
+
+def get_renderer(sample, **kwargs):
+ if isinstance(sample, (MeshWithPbrMaterial, MeshWithVoxel)):
+ renderer = PbrMeshRenderer()
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
+ renderer.rendering_options.near = kwargs.get('near', 1)
+ renderer.rendering_options.far = kwargs.get('far', 100)
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 2)
+ renderer.rendering_options.peel_layers = kwargs.get('peel_layers', 8)
+ elif isinstance(sample, Mesh):
+ renderer = MeshRenderer()
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
+ renderer.rendering_options.near = kwargs.get('near', 1)
+ renderer.rendering_options.far = kwargs.get('far', 100)
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 2)
+ renderer.rendering_options.chunk_size = kwargs.get('chunk_size', None)
+ elif isinstance(sample, Voxel):
+ renderer = VoxelRenderer()
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
+ renderer.rendering_options.near = kwargs.get('near', 0.1)
+ renderer.rendering_options.far = kwargs.get('far', 10.0)
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 2)
+ else:
+ raise ValueError(f'Unsupported sample type: {type(sample)}')
+ return renderer
+
+
+def render_frames(sample, extrinsics, intrinsics, options={}, verbose=True, **kwargs):
+ renderer = get_renderer(sample, **options)
+ rets = {}
+ for j, (extr, intr) in tqdm(enumerate(zip(extrinsics, intrinsics)), total=len(extrinsics), desc='Rendering', disable=not verbose):
+ res = renderer.render(sample, extr, intr, **kwargs)
+ for k, v in res.items():
+ if k not in rets: rets[k] = []
+ if v.dim() == 2: v = v[None].repeat(3, 1, 1)
+ rets[k].append(np.clip(v.detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8))
+ return rets
+
+
+def render_video(sample, resolution=1024, bg_color=(0, 0, 0), num_frames=120, r=2, fov=40, **kwargs):
+ yaws = -torch.linspace(0, 2 * 3.1415, num_frames) + np.pi/2
+ pitch = 0.25 + 0.5 * torch.sin(torch.linspace(0, 2 * 3.1415, num_frames))
+ yaws = yaws.tolist()
+ pitch = pitch.tolist()
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitch, r, fov)
+ return render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)
+
+
+def render_multiview(sample, resolution=512, nviews=30):
+ r = 2
+ fov = 40
+ cams = [sphere_hammersley_sequence(i, nviews) for i in range(nviews)]
+ yaws = [cam[0] for cam in cams]
+ pitchs = [cam[1] for cam in cams]
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, r, fov)
+ res = render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': (0, 0, 0)})
+ return res['color'], extrinsics, intrinsics
+
+
+def render_snapshot(samples, resolution=512, bg_color=(0, 0, 0), offset=(-16 / 180 * np.pi, 20 / 180 * np.pi), r=10, fov=8, nviews=4, **kwargs):
+ yaw = np.linspace(0, 2 * np.pi, nviews, endpoint=False)
+ yaw_offset = offset[0]
+ yaw = [y + yaw_offset for y in yaw]
+ pitch = [offset[1] for _ in range(nviews)]
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaw, pitch, r, fov)
+ return render_frames(samples, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)
+
+
+def make_pbr_vis_frames(result, resolution=1024):
+ num_frames = len(result['shaded'])
+ frames = []
+ for i in range(num_frames):
+ shaded = Image.fromarray(result['shaded'][i])
+ normal = Image.fromarray(result['normal'][i])
+ base_color = Image.fromarray(result['base_color'][i])
+ metallic = Image.fromarray(result['metallic'][i])
+ roughness = Image.fromarray(result['roughness'][i])
+ alpha = Image.fromarray(result['alpha'][i])
+ shaded = shaded.resize((resolution, resolution))
+ normal = normal.resize((resolution, resolution))
+ base_color = base_color.resize((resolution//2, resolution//2))
+ metallic = metallic.resize((resolution//2, resolution//2))
+ roughness = roughness.resize((resolution//2, resolution//2))
+ alpha = alpha.resize((resolution//2, resolution//2))
+ row1 = np.concatenate([shaded, normal], axis=1)
+ row2 = np.concatenate([base_color, metallic, roughness, alpha], axis=1)
+ frame = np.concatenate([row1, row2], axis=0)
+ frames.append(frame)
+ return frames
diff --git a/TRELLIS.2/trellis2/utils/vis_utils.py b/TRELLIS.2/trellis2/utils/vis_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e5f58e564aea50e4d80b0265220ee3fb382cd69
--- /dev/null
+++ b/TRELLIS.2/trellis2/utils/vis_utils.py
@@ -0,0 +1,44 @@
+from typing import *
+import numpy as np
+import torch
+from ..modules import sparse as sp
+from ..representations import Voxel
+from .render_utils import render_video
+
+
+def pca_color(feats: torch.Tensor, channels: Tuple[int, int, int] = (0, 1, 2)) -> torch.Tensor:
+ """
+ Apply PCA to the features and return the first three principal components.
+ """
+ feats = feats.detach()
+ u, s, v = torch.svd(feats)
+ color = u[:, channels]
+ color = (color - color.min(dim=0, keepdim=True)[0]) / (color.max(dim=0, keepdim=True)[0] - color.min(dim=0, keepdim=True)[0])
+ return color
+
+
+def vis_sparse_tensor(
+ x: sp.SparseTensor,
+ num_frames: int = 300,
+):
+ assert x.shape[0] == 1, "Only support batch size 1"
+ assert x.coords.shape[1] == 4, "Only support 3D coordinates"
+
+ coords = x.coords.cuda().detach()[:, 1:]
+ feats = x.feats.cuda().detach()
+ color = pca_color(feats)
+
+ resolution = max(list(x.spatial_shape))
+ resolution = int(2**np.ceil(np.log2(resolution)))
+
+ rep = Voxel(
+ origin=[-0.5, -0.5, -0.5],
+ voxel_size=1/resolution,
+ coords=coords,
+ attrs=color,
+ layout={
+ 'color': slice(0, 3),
+ }
+ )
+
+ return render_video(rep, colors_overwrite=color, num_frames=num_frames)['color']
diff --git a/app.py b/app.py
index 35cc0830278af95406c82545e668478d006909af..210b2730b05e3254d18a5ead7ec68e1b7c00fd1f 100644
--- a/app.py
+++ b/app.py
@@ -26,6 +26,7 @@ import gradio as gr
import spaces # HF ZeroGPU
from src import quota, ui_helpers, workspace
+from src.stages.stage1_generate import generate_trellis, generate_hunyuan
# ---------------------------------------------------------------------------
# ZeroGPU test function — proves that GPU allocation works.
@@ -80,8 +81,11 @@ def _stub(stage: str) -> str:
)
-def stub_generate(*_args, **_kwargs):
- return _stub("Stage 1: Generation")
+def handle_generate(images, model, quality, seed, _steps, _octree, tex_size, _symmetry):
+ """Dispatch to the correct generation backend based on model selection."""
+ if "TRELLIS" in model:
+ return generate_trellis(images, quality, int(seed), int(tex_size))
+ return generate_hunyuan(images, quality, int(seed), int(tex_size))
def stub_post_process(*_args, **_kwargs):
@@ -213,7 +217,7 @@ def build_ui() -> gr.Blocks:
with gr.Column(scale=1):
gen_status = gr.Markdown("*Awaiting input.*")
gen_btn.click(
- fn=stub_generate,
+ fn=handle_generate,
inputs=[gen_images, gen_model, gen_quality, gen_seed,
gen_steps, gen_octree, gen_tex_size, gen_symmetry],
outputs=gen_status,
diff --git a/requirements.txt b/requirements.txt
index 021824ebee7291305b5b680d043ee923877fd803..881275b9e46a7b310910f04d3ed8bad2a18ebbda 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
# Open3DForge — Dependencies
-# Gradio 5.x baseline. Compatible with current pydantic, starlette, huggingface_hub.
+# Top-level index for standard packages; CUDA packages via extra-index below.
+--extra-index-url https://download.pytorch.org/whl/cu124
# ===== Milestone 1: Foundation =====
gradio>=5.0
@@ -7,17 +8,29 @@ spaces # HF ZeroGPU decorator
numpy
pillow
-# ===== Milestone 2: Stage 1 Generation (uncomment as needed) =====
-# torch
-# torchvision
-# rembg[gpu]
-# transformers
-# diffusers
-# huggingface-hub
-# einops
-# scipy
-# # TRELLIS.2 — install from source in app.py or via setup script
-# # Hunyuan3D-2 — install from source in app.py or via setup script
+# ===== Milestone 2: Stage 1 — TRELLIS.2 Generation =====
+torch==2.6.0
+torchvision==0.21.0
+triton==3.2.0
+imageio==2.37.2
+imageio-ffmpeg==0.6.0
+tqdm==4.67.1
+easydict==1.13
+opencv-python-headless==4.12.0.88
+trimesh==4.10.1
+transformers==4.57.3
+zstandard==0.25.0
+kornia==0.8.2
+timm==1.0.22
+git+https://github.com/EasternJournalist/utils3d.git@9a4eb15e4021b67b12c460c7057d642626897ec8
+
+# TRELLIS.2 custom wheels (prebuilt for cp310 + CUDA 12.4)
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/cumesh-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/flex_gemm-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/o_voxel-0.0.1-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/nvdiffrast-0.4.0-cp310-cp310-linux_x86_64.whl
+https://github.com/JeffreyXiang/Storages/releases/download/Space_Wheels_251210/nvdiffrec_render-0.0.0-cp310-cp310-linux_x86_64.whl
# ===== Milestone 3: Stage 2 CPU pipeline =====
# trimesh[easy]
@@ -28,15 +41,16 @@ pillow
# coacd==1.0.4 # pinned: newer versions break on some HF environments
# ===== Milestone 4: Stage 2 GPU baking =====
-# nvdiffrast @ git+https://github.com/NVlabs/nvdiffrast.git
-# imageio
+# nvdiffrast already included above via TRELLIS.2 wheel
+# imageio already included above
# ===== Milestone 5: Stage 2 SDXL inpainting =====
+# diffusers
# accelerate
# safetensors
# ===== Milestone 7: Stage 3 Auto-rigging =====
-# # UniRig — install from source in app.py or via setup script
+# UniRig — install from source
# ===== Milestone 8: Export =====
# pygltflib
diff --git a/src/stages/__init__.py b/src/stages/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/stages/stage1_generate.py b/src/stages/stage1_generate.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1ab1e8977cd694ecd734598a795f3e8e1fb43cd
--- /dev/null
+++ b/src/stages/stage1_generate.py
@@ -0,0 +1,209 @@
+"""
+Stage 1 — Image to 3D generation.
+
+Backends:
+ - TRELLIS.2 (microsoft/TRELLIS.2-4B) — hard surface, single-image
+ - Hunyuan3D-2.1 — organic/characters [Milestone 2b stub]
+
+ZeroGPU rule: pipeline must be initialised at module level.
+The @spaces.GPU functions allocate the H200 on-demand.
+"""
+from __future__ import annotations
+
+import os
+import sys
+import time
+from pathlib import Path
+
+import numpy as np
+import torch
+from PIL import Image
+
+import gradio as gr
+import spaces
+
+# ---------------------------------------------------------------------------
+# Paths + environment — must happen before any trellis2 import
+# ---------------------------------------------------------------------------
+_REPO_ROOT = Path(__file__).resolve().parent.parent.parent
+_TRELLIS_DIR = _REPO_ROOT / "TRELLIS.2"
+
+os.environ.setdefault("OPENCV_IO_ENABLE_OPENEXR", "1")
+os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
+os.environ.setdefault("ATTN_BACKEND", "flash_attn_3")
+os.environ["FLEX_GEMM_AUTOTUNE_CACHE_PATH"] = str(_TRELLIS_DIR / "autotune_cache.json")
+os.environ.setdefault("FLEX_GEMM_AUTOTUNER_VERBOSE", "0")
+
+if str(_TRELLIS_DIR) not in sys.path:
+ sys.path.insert(0, str(_TRELLIS_DIR))
+
+# ---------------------------------------------------------------------------
+# Pipeline imports (after sys.path is patched)
+# ---------------------------------------------------------------------------
+from trellis2.pipelines import Trellis2ImageTo3DPipeline # noqa: E402
+import o_voxel # noqa: E402
+
+from src import workspace # noqa: E402
+from src.workspace import CURRENT # noqa: E402
+
+# ---------------------------------------------------------------------------
+# Module-level pipeline init (ZeroGPU requirement)
+# low_vram=True (default): .cuda() just records target device;
+# model weights stay on CPU and move to GPU lazily inside each forward pass.
+# ---------------------------------------------------------------------------
+pipeline_trellis: Trellis2ImageTo3DPipeline = (
+ Trellis2ImageTo3DPipeline.from_pretrained("microsoft/TRELLIS.2-4B")
+)
+pipeline_trellis.cuda()
+
+# ---------------------------------------------------------------------------
+# Quality presets → TRELLIS.2 sampler parameters
+# ---------------------------------------------------------------------------
+_PRESETS = {
+ "Fast (~30s)": {
+ "pipeline_type": "512",
+ "steps": 8,
+ "decimation_target": 50_000,
+ },
+ "Balanced (~60s)": {
+ "pipeline_type": "1024_cascade",
+ "steps": 12,
+ "decimation_target": 100_000,
+ },
+ "Hero (~90s)": {
+ "pipeline_type": "1536_cascade",
+ "steps": 16,
+ "decimation_target": 200_000,
+ },
+}
+
+
+# ---------------------------------------------------------------------------
+# Helpers
+# ---------------------------------------------------------------------------
+
+def _open_first_image(files: list | None) -> Image.Image | None:
+ """Open the first item from a gr.File(file_count='multiple') list."""
+ if not files:
+ return None
+ f = files[0]
+ path = f.name if hasattr(f, "name") else str(f)
+ return Image.open(path)
+
+
+def _export_glb(mesh, res: int, deci_target: int, tex_size: int, out_path: Path) -> None:
+ glb = o_voxel.postprocess.to_glb(
+ vertices=mesh.vertices,
+ faces=mesh.faces,
+ attr_volume=mesh.attrs,
+ coords=mesh.coords,
+ attr_layout=pipeline_trellis.pbr_attr_layout,
+ grid_size=res,
+ aabb=[[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]],
+ decimation_target=deci_target,
+ texture_size=tex_size,
+ remesh=True,
+ remesh_band=1,
+ remesh_project=0,
+ use_tqdm=False,
+ )
+ glb.export(str(out_path), extension_webp=True)
+
+
+def _count_faces(glb_path: Path) -> tuple[int, int]:
+ try:
+ import trimesh
+ m = trimesh.load(str(glb_path), force="mesh")
+ return len(m.faces), len(m.vertices)
+ except Exception:
+ return 0, 0
+
+
+# ---------------------------------------------------------------------------
+# TRELLIS.2 generation
+# ---------------------------------------------------------------------------
+
+@spaces.GPU(duration=180)
+def generate_trellis(
+ images: list | None,
+ quality: str,
+ seed: int,
+ tex_size: int = 2048,
+) -> str:
+ """Run TRELLIS.2 image-to-3D. Returns a Markdown status string."""
+ t0 = time.time()
+
+ image = _open_first_image(images)
+ if image is None:
+ return "❌ Please upload at least one reference image."
+
+ preset = _PRESETS.get(quality, _PRESETS["Balanced (~60s)"])
+ steps = preset["steps"]
+
+ # Sampler parameter sets — guidance values match staging-app defaults
+ _ss = {"steps": steps, "guidance_strength": 7.5, "guidance_rescale": 0.7, "rescale_t": 5.0}
+ _sh = {"steps": steps, "guidance_strength": 7.5, "guidance_rescale": 0.5, "rescale_t": 3.0}
+ _tx = {"steps": steps, "guidance_strength": 1.0, "guidance_rescale": 0.0, "rescale_t": 3.0}
+
+ # Clear workspace before writing new outputs
+ workspace.reset_current()
+ state = workspace.reset_state()
+
+ outputs, latents = pipeline_trellis.run(
+ image,
+ seed=int(seed),
+ preprocess_image=True, # uses pipeline's built-in BiRefNet rembg
+ sparse_structure_sampler_params=_ss,
+ shape_slat_sampler_params=_sh,
+ tex_slat_sampler_params=_tx,
+ pipeline_type=preset["pipeline_type"],
+ return_latent=True,
+ )
+
+ mesh = outputs[0]
+ mesh.simplify(16_777_216) # nvdiffrast face limit
+ _shape_slat, _tex_slat, res = latents
+
+ high_poly_path = CURRENT / "high_poly.glb"
+ raw_gen_path = CURRENT / "raw_gen.glb"
+ tex_size_int = int(tex_size)
+
+ # High-poly: no decimation — kept for Stage 2 normal/albedo baking
+ _export_glb(mesh, res, 16_000_000, tex_size_int, high_poly_path)
+ # Working mesh: user's quality-preset target face count
+ _export_glb(mesh, res, preset["decimation_target"], tex_size_int, raw_gen_path)
+
+ torch.cuda.empty_cache()
+
+ face_count, vertex_count = _count_faces(raw_gen_path)
+
+ state.high_poly_glb = high_poly_path
+ state.raw_gen_glb = raw_gen_path
+ state.model_used = "TRELLIS.2"
+ state.face_count = face_count
+ state.vertex_count = vertex_count
+
+ elapsed = time.time() - t0
+ return (
+ f"✅ **Generated with TRELLIS.2** · {quality}\n\n"
+ f"- Faces: {face_count:,} · Vertices: {vertex_count:,}\n"
+ f"- Time: {elapsed:.1f}s\n\n"
+ f"Scroll down to see the result in the 3D viewer. "
+ f"High-poly saved for Stage 2 baking."
+ )
+
+
+# ---------------------------------------------------------------------------
+# Hunyuan3D-2.1 (Milestone 2b — stub)
+# ---------------------------------------------------------------------------
+
+def generate_hunyuan(
+ images: list | None,
+ quality: str,
+ seed: int,
+ tex_size: int = 2048,
+) -> str:
+ return (
+ "🚧 **Hunyuan3D-2.1** — not wired yet.\n\n"
+ "Will be enabled in Milestone 2b. Use TRELLIS.2 for now."
+ )