diff --git a/README.md b/README.md index 113a323..cdddffd 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ # ComfyUI-Data-Analysis -## Update (March 7, 2025) -You can now use newly added nodes to train a machine learning model for image classification with your own image data **without any coding** from scratch. - -Check out [the new tutorial to classify dogs and cats](docs/dog_cat_classification_model_training.md) - +## Update (March 10, 2025) +All PyTorch nodes have been moved to a separate extension. If you're using PyTorch wrappers, install the [ComfyUI-Pt-Wrapper extension](https://github.com/HowToSD/ComfyUI-Pt-Wrapper). --- ![Baseball tutorial](docs/images/baseball_question.jpg) ## How Can We Figure Out Which MLB Player Had the Most Hits Per Year? @@ -22,15 +19,11 @@ I hope you find it useful and engaging for data exploration. ![Baseball tutorial](docs/images/baseball_final.png) **ComfyUI-Data-Analysis** is an extension for ComfyUI that provides custom nodes for data analysis using Pandas, Seaborn, and Matplotlib within ComfyUI. - -Originally designed for structural data analysis, this extension is for you if you: -- Want access to PyTorch's low-level methods (e.g., `add`, `div`, `max`, `where`, `scatter`, `gather`) to manipulate PyTorch tensors or extract information. -- Are comfortable with ComfyUI and want to learn foundational PyTorch methods **without writing a single line of code**. -- Want to analyze structural data (tabular data) using ComfyUI's node system. +Especially, this is suited if you want to analyze structural data (tabular data) using ComfyUI's node system. ## Features -**ComfyUI-Data-Analysis** includes numerous custom nodes that wrap Pandas and PyTorch. +**ComfyUI-Data-Analysis** includes numerous custom nodes that wrap Pandas, Matplotlib and Seaborn. For a complete list, see the [Node Reference](docs/reference/node_reference.md). These nodes allow you to conduct complex analyses in an intuitive, graphical way. You can also combine them with other ComfyUI custom nodes to fit your workflow needs (e.g., integrating images). diff --git a/__init__.py b/__init__.py index 2ddc986..3e295b0 100644 --- a/__init__.py +++ b/__init__.py @@ -171,112 +171,6 @@ from .modules.pandas_wrapper.pandas_var import PandasVar from .modules.pandas_wrapper.pandas_vertical_concat import PandasVerticalConcat from .modules.pandas_wrapper.pandas_vertical_split import PandasVerticalSplit from .modules.pandas_wrapper.pandas_xs import PandasXs -from .modules.pytorch_wrapper.pt_abs import PtAbs -from .modules.pytorch_wrapper.pt_acos import PtAcos -from .modules.pytorch_wrapper.pt_add import PtAdd -from .modules.pytorch_wrapper.pt_arange import PtArange -from .modules.pytorch_wrapper.pt_argmax import PtArgmax -from .modules.pytorch_wrapper.pt_argmin import PtArgmin -from .modules.pytorch_wrapper.pt_asin import PtAsin -from .modules.pytorch_wrapper.pt_atan import PtAtan -from .modules.pytorch_wrapper.pt_bitwise_and import PtBitwiseAnd -from .modules.pytorch_wrapper.pt_bitwise_left_shift import PtBitwiseLeftShift -from .modules.pytorch_wrapper.pt_bitwise_not import PtBitwiseNot -from .modules.pytorch_wrapper.pt_bitwise_or import PtBitwiseOr -from .modules.pytorch_wrapper.pt_bitwise_right_shift import PtBitwiseRightShift -from .modules.pytorch_wrapper.pt_bitwise_xor import PtBitwiseXor -from .modules.pytorch_wrapper.pt_bmm import PtBmm -from .modules.pytorch_wrapper.pt_bool_create import PtBoolCreate -from .modules.pytorch_wrapper.pt_cos import PtCos -from .modules.pytorch_wrapper.pt_cosh import PtCosh -from .modules.pytorch_wrapper.pt_crop import PtCrop -from .modules.pytorch_wrapper.pt_data_loader import PtDataLoader -from .modules.pytorch_wrapper.pt_div import PtDiv -from .modules.pytorch_wrapper.pt_einsum import PtEinsum -from .modules.pytorch_wrapper.pt_eq import PtEq -from .modules.pytorch_wrapper.pt_evaluate_classification_model import PtEvaluateClassificationModel -from .modules.pytorch_wrapper.pt_exp import PtExp -from .modules.pytorch_wrapper.pt_flatten import PtFlatten -from .modules.pytorch_wrapper.pt_float_create import PtFloatCreate -from .modules.pytorch_wrapper.pt_floor_divide import PtFloorDiv -from .modules.pytorch_wrapper.pt_from_image import PtFromImage -from .modules.pytorch_wrapper.pt_from_image_transpose import PtFromImageTranspose -from .modules.pytorch_wrapper.pt_from_latent import PtFromLatent -from .modules.pytorch_wrapper.pt_from_numpy import PtFromNumpy -from .modules.pytorch_wrapper.pt_full import PtFull -from .modules.pytorch_wrapper.pt_gather import PtGather -from .modules.pytorch_wrapper.pt_ge import PtGe -from .modules.pytorch_wrapper.pt_gt import PtGt -from .modules.pytorch_wrapper.pt_index_select import PtIndexSelect -from .modules.pytorch_wrapper.pt_int_create import PtIntCreate -from .modules.pytorch_wrapper.pt_interpolate_by_scale_factor import PtInterpolateByScaleFactor -from .modules.pytorch_wrapper.pt_interpolate_to_size import PtInterpolateToSize -from .modules.pytorch_wrapper.pt_le import PtLe -from .modules.pytorch_wrapper.pt_linspace import PtLinspace -from .modules.pytorch_wrapper.pt_load_model import PtLoadModel -from .modules.pytorch_wrapper.pt_log import PtLog -from .modules.pytorch_wrapper.pt_logical_and import PtLogicalAnd -from .modules.pytorch_wrapper.pt_logical_not import PtLogicalNot -from .modules.pytorch_wrapper.pt_logical_or import PtLogicalOr -from .modules.pytorch_wrapper.pt_logical_xor import PtLogicalXor -from .modules.pytorch_wrapper.pt_lt import PtLt -from .modules.pytorch_wrapper.pt_masked_select import PtMaskedSelect -from .modules.pytorch_wrapper.pt_matmul import PtMatMul -from .modules.pytorch_wrapper.pt_max import PtMax -from .modules.pytorch_wrapper.pt_mean import PtMean -from .modules.pytorch_wrapper.pt_median import PtMedian -from .modules.pytorch_wrapper.pt_min import PtMin -from .modules.pytorch_wrapper.pt_mm import PtMm -from .modules.pytorch_wrapper.pt_mul import PtMul -from .modules.pytorch_wrapper.pt_ne import PtNe -from .modules.pytorch_wrapper.pt_neg import PtNeg -from .modules.pytorch_wrapper.pt_ones import PtOnes -from .modules.pytorch_wrapper.pt_pad import PtPad -from .modules.pytorch_wrapper.pt_permute import PtPermute -from .modules.pytorch_wrapper.pt_pow import PtPow -from .modules.pytorch_wrapper.pt_predict_classification_model import PtPredictClassificationModel -from .modules.pytorch_wrapper.pt_prod import PtProd -from .modules.pytorch_wrapper.pt_rand import PtRand -from .modules.pytorch_wrapper.pt_rand_int import PtRandInt -from .modules.pytorch_wrapper.pt_randn import PtRandn -from .modules.pytorch_wrapper.pt_remainder import PtRemainder -from .modules.pytorch_wrapper.pt_reshape import PtReshape -from .modules.pytorch_wrapper.pt_save_model import PtSaveModel -from .modules.pytorch_wrapper.pt_scatter import PtScatter -from .modules.pytorch_wrapper.pt_show_size import PtShowSize -from .modules.pytorch_wrapper.pt_show_text import PtShowText -from .modules.pytorch_wrapper.pt_sin import PtSin -from .modules.pytorch_wrapper.pt_sinh import PtSinh -from .modules.pytorch_wrapper.pt_size import PtSize -from .modules.pytorch_wrapper.pt_size_create import PtSizeCreate -from .modules.pytorch_wrapper.pt_size_to_numpy import PtSizeToNumpy -from .modules.pytorch_wrapper.pt_size_to_string import PtSizeToString -from .modules.pytorch_wrapper.pt_sqrt import PtSqrt -from .modules.pytorch_wrapper.pt_squeeze import PtSqueeze -from .modules.pytorch_wrapper.pt_std import PtStd -from .modules.pytorch_wrapper.pt_sub import PtSub -from .modules.pytorch_wrapper.pt_sum import PtSum -from .modules.pytorch_wrapper.pt_tan import PtTan -from .modules.pytorch_wrapper.pt_tanh import PtTanh -from .modules.pytorch_wrapper.pt_to_image import PtToImage -from .modules.pytorch_wrapper.pt_to_image_transpose import PtToImageTranspose -from .modules.pytorch_wrapper.pt_to_latent import PtToLatent -from .modules.pytorch_wrapper.pt_to_numpy import PtToNumpy -from .modules.pytorch_wrapper.pt_to_rgb_tensors import PtToRgbTensors -from .modules.pytorch_wrapper.pt_train_classification_model import PtTrainClassificationModel -from .modules.pytorch_wrapper.pt_unsqueeze import PtUnsqueeze -from .modules.pytorch_wrapper.pt_var import PtVar -from .modules.pytorch_wrapper.pt_view import PtView -from .modules.pytorch_wrapper.pt_where import PtWhere -from .modules.pytorch_wrapper.pt_zeros import PtZeros -from .modules.pytorch_wrapper.ptn_conv_model import PtnConvModel -from .modules.pytorch_wrapper.ptn_linear_model import PtnLinearModel -from .modules.pytorch_wrapper.pto_adam import PtoAdam -from .modules.pytorch_wrapper.ptv_dataset import PtvDataset -from .modules.pytorch_wrapper.ptv_dataset_loader import PtvDatasetLoader -from .modules.pytorch_wrapper.ptv_image_folder_dataset import PtvImageFolderDataset -from .modules.pytorch_wrapper.ptv_transforms_resize import PtvTransformsResize -from .modules.pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor from .modules.seaborn_wrapper.sns_bar import SNSBar from .modules.seaborn_wrapper.sns_boxplot import SNSBoxplot from .modules.seaborn_wrapper.sns_heatmap import SNSHeatmap @@ -453,112 +347,6 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasVerticalConcat": PandasVerticalConcat, "PandasVerticalSplit": PandasVerticalSplit, "PandasXs": PandasXs, - "PtAbs": PtAbs, - "PtAcos": PtAcos, - "PtAdd": PtAdd, - "PtArange": PtArange, - "PtArgmax": PtArgmax, - "PtArgmin": PtArgmin, - "PtAsin": PtAsin, - "PtAtan": PtAtan, - "PtBitwiseAnd": PtBitwiseAnd, - "PtBitwiseLeftShift": PtBitwiseLeftShift, - "PtBitwiseNot": PtBitwiseNot, - "PtBitwiseOr": PtBitwiseOr, - "PtBitwiseRightShift": PtBitwiseRightShift, - "PtBitwiseXor": PtBitwiseXor, - "PtBmm": PtBmm, - "PtBoolCreate": PtBoolCreate, - "PtCos": PtCos, - "PtCosh": PtCosh, - "PtCrop": PtCrop, - "PtDataLoader": PtDataLoader, - "PtDiv": PtDiv, - "PtEinsum": PtEinsum, - "PtEq": PtEq, - "PtEvaluateClassificationModel": PtEvaluateClassificationModel, - "PtExp": PtExp, - "PtFlatten": PtFlatten, - "PtFloatCreate": PtFloatCreate, - "PtFloorDiv": PtFloorDiv, - "PtFromImage": PtFromImage, - "PtFromImageTranspose": PtFromImageTranspose, - "PtFromLatent": PtFromLatent, - "PtFromNumpy": PtFromNumpy, - "PtFull": PtFull, - "PtGather": PtGather, - "PtGe": PtGe, - "PtGt": PtGt, - "PtIndexSelect": PtIndexSelect, - "PtIntCreate": PtIntCreate, - "PtInterpolateByScaleFactor": PtInterpolateByScaleFactor, - "PtInterpolateToSize": PtInterpolateToSize, - "PtLe": PtLe, - "PtLinspace": PtLinspace, - "PtLoadModel": PtLoadModel, - "PtLog": PtLog, - "PtLogicalAnd": PtLogicalAnd, - "PtLogicalNot": PtLogicalNot, - "PtLogicalOr": PtLogicalOr, - "PtLogicalXor": PtLogicalXor, - "PtLt": PtLt, - "PtMaskedSelect": PtMaskedSelect, - "PtMatMul": PtMatMul, - "PtMax": PtMax, - "PtMean": PtMean, - "PtMedian": PtMedian, - "PtMin": PtMin, - "PtMm": PtMm, - "PtMul": PtMul, - "PtNe": PtNe, - "PtNeg": PtNeg, - "PtOnes": PtOnes, - "PtPad": PtPad, - "PtPermute": PtPermute, - "PtPow": PtPow, - "PtPredictClassificationModel": PtPredictClassificationModel, - "PtProd": PtProd, - "PtRand": PtRand, - "PtRandInt": PtRandInt, - "PtRandn": PtRandn, - "PtRemainder": PtRemainder, - "PtReshape": PtReshape, - "PtSaveModel": PtSaveModel, - "PtScatter": PtScatter, - "PtShowSize": PtShowSize, - "PtShowText": PtShowText, - "PtSin": PtSin, - "PtSinh": PtSinh, - "PtSize": PtSize, - "PtSizeCreate": PtSizeCreate, - "PtSizeToNumpy": PtSizeToNumpy, - "PtSizeToString": PtSizeToString, - "PtSqrt": PtSqrt, - "PtSqueeze": PtSqueeze, - "PtStd": PtStd, - "PtSub": PtSub, - "PtSum": PtSum, - "PtTan": PtTan, - "PtTanh": PtTanh, - "PtToImage": PtToImage, - "PtToImageTranspose": PtToImageTranspose, - "PtToLatent": PtToLatent, - "PtToNumpy": PtToNumpy, - "PtToRgbTensors": PtToRgbTensors, - "PtTrainClassificationModel": PtTrainClassificationModel, - "PtUnsqueeze": PtUnsqueeze, - "PtVar": PtVar, - "PtView": PtView, - "PtWhere": PtWhere, - "PtZeros": PtZeros, - "PtnConvModel": PtnConvModel, - "PtnLinearModel": PtnLinearModel, - "PtoAdam": PtoAdam, - "PtvDataset": PtvDataset, - "PtvDatasetLoader": PtvDatasetLoader, - "PtvImageFolderDataset": PtvImageFolderDataset, - "PtvTransformsResize": PtvTransformsResize, - "PtvTransformsToTensor": PtvTransformsToTensor, "PyDatetimeToString": PyDatetimeToString, "PyFloatToString": PyFloatToString, "PyIntToString": PyIntToString, @@ -746,112 +534,6 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasVerticalConcat": "Pandas Vertical Concat", "PandasVerticalSplit": "Pandas Vertical Split", "PandasXs": "Pandas Xs", - "PtAbs": "Pt Abs", - "PtAcos": "Pt Acos", - "PtAdd": "Pt Add", - "PtArange": "Pt Arange", - "PtArgmax": "Pt Argmax", - "PtArgmin": "Pt Argmin", - "PtAsin": "Pt Asin", - "PtAtan": "Pt Atan", - "PtBitwiseAnd": "Pt Bitwise And", - "PtBitwiseLeftShift": "Pt Bitwise Left Shift", - "PtBitwiseNot": "Pt Bitwise Not", - "PtBitwiseOr": "Pt Bitwise Or", - "PtBitwiseRightShift": "Pt Bitwise Right Shift", - "PtBitwiseXor": "Pt Bitwise Xor", - "PtBmm": "Pt Bmm", - "PtBoolCreate": "Pt Bool Create", - "PtCos": "Pt Cos", - "PtCosh": "Pt Cosh", - "PtCrop": "Pt Crop", - "PtDataLoader": "Pt Data Loader", - "PtDiv": "Pt Div", - "PtEinsum": "Pt Einsum", - "PtEq": "Pt Eq", - "PtEvaluateClassificationModel": "Pt Evaluate Classification Model", - "PtExp": "Pt Exp", - "PtFlatten": "Pt Flatten", - "PtFloatCreate": "Pt Float Create", - "PtFloorDiv": "Pt Floor Div", - "PtFromImage": "Pt From Image", - "PtFromImageTranspose": "Pt From Image Transpose", - "PtFromLatent": "Pt From Latent", - "PtFromNumpy": "Pt From Numpy", - "PtFull": "Pt Full", - "PtGather": "Pt Gather", - "PtGe": "Pt Ge", - "PtGt": "Pt Gt", - "PtIndexSelect": "Pt Index Select", - "PtIntCreate": "Pt Int Create", - "PtInterpolateByScaleFactor": "Pt Interpolate By Scale Factor", - "PtInterpolateToSize": "Pt Interpolate To Size", - "PtLe": "Pt Le", - "PtLinspace": "Pt Linspace", - "PtLoadModel": "Pt Load Model", - "PtLog": "Pt Log", - "PtLogicalAnd": "Pt Logical And", - "PtLogicalNot": "Pt Logical Not", - "PtLogicalOr": "Pt Logical Or", - "PtLogicalXor": "Pt Logical Xor", - "PtLt": "Pt Lt", - "PtMaskedSelect": "Pt Masked Select", - "PtMatMul": "Pt Mat Mul", - "PtMax": "Pt Max", - "PtMean": "Pt Mean", - "PtMedian": "Pt Median", - "PtMin": "Pt Min", - "PtMm": "Pt Mm", - "PtMul": "Pt Mul", - "PtNe": "Pt Ne", - "PtNeg": "Pt Neg", - "PtOnes": "Pt Ones", - "PtPad": "Pt Pad", - "PtPermute": "Pt Permute", - "PtPow": "Pt Pow", - "PtPredictClassificationModel": "Pt Predict Classification Model", - "PtProd": "Pt Prod", - "PtRand": "Pt Rand", - "PtRandInt": "Pt Rand Int", - "PtRandn": "Pt Randn", - "PtRemainder": "Pt Remainder", - "PtReshape": "Pt Reshape", - "PtSaveModel": "Pt Save Model", - "PtScatter": "Pt Scatter", - "PtShowSize": "Pt Show Size", - "PtShowText": "Pt Show Text", - "PtSin": "Pt Sin", - "PtSinh": "Pt Sinh", - "PtSize": "Pt Size", - "PtSizeCreate": "Pt Size Create", - "PtSizeToNumpy": "Pt Size To Numpy", - "PtSizeToString": "Pt Size To String", - "PtSqrt": "Pt Sqrt", - "PtSqueeze": "Pt Squeeze", - "PtStd": "Pt Std", - "PtSub": "Pt Sub", - "PtSum": "Pt Sum", - "PtTan": "Pt Tan", - "PtTanh": "Pt Tanh", - "PtToImage": "Pt To Image", - "PtToImageTranspose": "Pt To Image Transpose", - "PtToLatent": "Pt To Latent", - "PtToNumpy": "Pt To Numpy", - "PtToRgbTensors": "Pt To Rgb Tensors", - "PtTrainClassificationModel": "Pt Train Classification Model", - "PtUnsqueeze": "Pt Unsqueeze", - "PtVar": "Pt Var", - "PtView": "Pt View", - "PtWhere": "Pt Where", - "PtZeros": "Pt Zeros", - "PtnConvModel": "Ptn Conv Model", - "PtnLinearModel": "Ptn Linear Model", - "PtoAdam": "Pto Adam", - "PtvDataset": "Ptv Dataset", - "PtvDatasetLoader": "Ptv Dataset Loader", - "PtvImageFolderDataset": "Ptv Image Folder Dataset", - "PtvTransformsResize": "Ptv Transforms Resize", - "PtvTransformsToTensor": "Ptv Transforms To Tensor", "PyDatetimeToString": "Py Datetime To String", "PyFloatToString": "Py Float To String", "PyIntToString": "Py Int To String", diff --git a/docs/dog_cat_classification_model_training.md b/docs/dog_cat_classification_model_training.md deleted file mode 100644 index 68f3c13..0000000 --- a/docs/dog_cat_classification_model_training.md +++ /dev/null @@ -1,137 +0,0 @@ -# Dog cat classification model training tutorial -This tutorial covers how to use **ComfyUI Data Analysis** to train an image classification model with your own image dataset. -We'll use a **dog and cat image dataset** created specifically for this tutorial, which is available publicly on [my GitHub repo](https://github.com/HowToSD/dog_and_cat_dataset). - -Once you complete the tutorial, you can experiment with your own images. - -**Disclaimer:** The model architecture is a traditional convolutional neural network (CNN) and is **not state-of-the-art**. This choice keeps the model small, enabling faster training and easier explanation. - ---- - -## Overview of Steps - -1. Downloading the dog and cat dataset from the GitHub repo -2. Edit the training workflow -3. Run the training workflow -4. Edit the evaluation workflow -5. Run the evaluation workflow - ---- - -## 1. Download the Dog & Cat Dataset - -Visit [the GitHub repo](https://github.com/HowToSD/dog_and_cat_dataset) and go to the **Releases** page. -Click **"Source code (zip)"** to download the zip that contains all the images. -Extract the ZIP file using an unarchiver. - -The dataset follows this directory structure: - -``` -dog_and_cat - train - cats - dogs - - val - cats - dogs -``` - - -Take note of the **full paths** to the `train` and `val` directories, as you'll need them in the next step. - ---- - -## 2. Editing the Training Workflow - -Drag and drop the below file into ComfyUI: -``` -examples/workflow/dog_cat_classification_train_model.json -``` -Some nodes will be marked red, indicating they require edits. -The only required changes are the **train** and **val** dataset paths. -Replace them with the paths noted earlier. - ---- - -## 3. Running the Training Workflow - -Click **Queue** to start training. - -Monitor the console for errors. If training runs smoothly, you should see output like this: - -``` -Epoch (train) 1/20, Loss: 0.6865 -Epoch (val) 1/20, Loss: 0.6801 -Epoch (train) 2/20, Loss: 0.6216 -Epoch (val) 2/20, Loss: 0.5710 -Epoch (train) 3/20, Loss: 0.4998 -Epoch (val) 3/20, Loss: 0.4716 -Epoch (train) 4/20, Loss: 0.3827 -Epoch (val) 4/20, Loss: 0.4045 -Epoch (train) 5/20, Loss: 0.2897 -Epoch (val) 5/20, Loss: 0.3297 -Epoch (train) 6/20, Loss: 0.2243 -Epoch (val) 6/20, Loss: 0.2925 -Epoch (train) 7/20, Loss: 0.1603 -Epoch (val) 7/20, Loss: 0.2916 -Epoch (train) 8/20, Loss: 0.1102 -Epoch (val) 8/20, Loss: 0.3216 -Epoch (train) 9/20, Loss: 0.0916 -Epoch (val) 9/20, Loss: 0.2706 -Epoch (train) 10/20, Loss: 0.0522 -Epoch (val) 10/20, Loss: 0.2220 -Epoch (train) 11/20, Loss: 0.0481 -Epoch (val) 11/20, Loss: 0.2820 -Epoch (train) 12/20, Loss: 0.0228 -Epoch (val) 12/20, Loss: 0.2899 -Epoch (train) 13/20, Loss: 0.0130 -Epoch (val) 13/20, Loss: 0.3056 -Epoch (train) 14/20, Loss: 0.0137 -Epoch (val) 14/20, Loss: 0.3070 -Epoch (train) 15/20, Loss: 0.0200 -Epoch (val) 15/20, Loss: 0.2714 -Epoch (train) 16/20, Loss: 0.0313 -Epoch (val) 16/20, Loss: 0.3108 -Epoch (train) 17/20, Loss: 0.0125 -Epoch (val) 17/20, Loss: 0.3388 -Epoch (train) 18/20, Loss: 0.0174 -Epoch (val) 18/20, Loss: 0.2989 -Epoch (train) 19/20, Loss: 0.0017 -Epoch (val) 19/20, Loss: 0.3165 -Epoch (train) 20/20, Loss: 0.0009 -Epoch (val) 20/20, Loss: 0.3582 -Prompt executed in 253.64 seconds -``` - -If you encounter an error: -- Ensure dataset paths are correct. -- Reduce **batch size** if your GPU runs out of memory (OOM error). - -Once training completes, a **line chart** displaying training progress will appear at the bottom right of the canvas. You don’t need to interpret it initially. - ---- - -## 4. Editing the Evaluation Workflow -Now, let's verify if the model was trained correctly. In this step, we'll feed the validation data into the trained model and compute metrics to assess its performance. - -Drag and drop the below file into ComfyUI: -``` -examples/workflow/dog_cat_classification_eval_model.json -``` - -into **ComfyUI**. - -Update the **val dataset path**. - ---- - -## 5. Running the Evaluation Workflow - -Click **Queue**. The evaluation process runs much faster than training. - -Check the **Accuracy** node—it should display a value around **0.9**, confirming successful model training. - -Congratulations! You’ve successfully trained a machine learning model from scratch without writing a single line of code. - -Now, you can use your own images to train the model in the same way. \ No newline at end of file diff --git a/docs/images/conv_eval.png b/docs/images/conv_eval.png deleted file mode 100644 index 03ae6b9..0000000 Binary files a/docs/images/conv_eval.png and /dev/null differ diff --git a/docs/images/conv_train.png b/docs/images/conv_train.png deleted file mode 100644 index 442c4f3..0000000 Binary files a/docs/images/conv_train.png and /dev/null differ diff --git a/docs/images/conv_train2.png b/docs/images/conv_train2.png deleted file mode 100644 index de5a9a2..0000000 Binary files a/docs/images/conv_train2.png and /dev/null differ diff --git a/docs/images/fashion_mnist_eval.png b/docs/images/fashion_mnist_eval.png deleted file mode 100644 index 8278581..0000000 Binary files a/docs/images/fashion_mnist_eval.png and /dev/null differ diff --git a/docs/images/fashion_mnist_train.png b/docs/images/fashion_mnist_train.png deleted file mode 100644 index c74a788..0000000 Binary files a/docs/images/fashion_mnist_train.png and /dev/null differ diff --git a/docs/model_training.md b/docs/model_training.md deleted file mode 100644 index dbfc555..0000000 --- a/docs/model_training.md +++ /dev/null @@ -1,49 +0,0 @@ -# Model Training - -Experimental PyTorch model training has been added. -No coding is required. Training is as simple as a single click! -Currently, only classification is supported. - -The system is designed to be modular. For example, to switch from a linear model to a convolutional model, you only need to replace the model node (see screenshot below). - -You can choose to: -* Use your own images -* Use a public dataset - -## Using Your Own Images - -Check out [the dog and cat classification tutorial](dog_cat_classification_model_training.md). - -## Public Datasets - -Currently, only Fashion MNIST has been tested. Other public datasets have not been verified yet, though they may work. -If you try one and it doesn't work, please create an issue so I can investigate adding support. - -To use the Fashion MNIST dataset, simply drag and drop the workflow files below into ComfyUI. The model will be downloaded automatically. - -Linear model -* Training: examples/fashion_mnist_train.json -* Evaluation: examples/fashion_mnist_eval.json - -Convolutional model -* Training: examples/fashion_mnist_train_conv.json -* Evaluation: examples/fashion_mnist_eval_conv.json - -These training workflows train a FashionMNIST model from scratch effortlessly. - -### Training workflow -**Linear model** -![Train](images/fashion_mnist_train.png) - -**Conv model** -![Train](images/conv_train.png) - -*Close up of the conv node* -![Train](images/conv_train2.png) - -### Eval workflow -**Linear model** -![Eval](images/fashion_mnist_eval.png) - -**Conv model** -![Eval](images/conv_eval.png) diff --git a/docs/reference/node_reference.md b/docs/reference/node_reference.md index cc5b145..3a1e5ae 100644 --- a/docs/reference/node_reference.md +++ b/docs/reference/node_reference.md @@ -99,8 +99,6 @@ | [Pandas Show Series](pandas_show_series.md) | Displays a Pandas Series as text. | | [Pandas Show Text](pandas_show_text.md) | Displays a string. | | [Pandas To String](pandas_to_string.md) | Converts a pandas DataFrame to a string representation. | -| [Pt Show Size](pt_show_size.md) | Displays PyTorch Size object as a string. | -| [Pt Show Text](pt_show_text.md) | Displays PyTorch tensor as a string. Note that the tensor is partially printed out when | ## IO | Node | Description | | --- | --- | @@ -127,7 +125,6 @@ | [Pandas Load JSON](pandas_load_json.md) | Loads JSON files into a pandas DataFrame. | | [Pandas Save CSV](pandas_save_csv.md) | Saves a PandasDataFrame to a CSV file. | | [Pandas Save JSON](pandas_save_json.md) | Saves a PandasDataFrame to a JSON file. | -| [Pt Save Model](pt_save_model.md) | A wrapper class for saving a PyTorch model. | ## Logical operations | Node | Description | | --- | --- | @@ -178,151 +175,6 @@ | [SNS Line Plot](sns_line.md) | Generates a line plot from a pandas DataFrame using Seaborn. | | [SNS Pairplot](sns_pairplot.md) | Generates a pairplot from a Pandas DataFrame using Seaborn. | | [SNS Scatter Plot](sns_scatter.md) | Generates a scatter plot from a pandas DataFrame using Seaborn. | -## PyTorch wrapper - Arithmetic operations -| Node | Description | -| --- | --- | -| [Pt Add](pt_add.md) | Adds two PyTorch tensors. | -| [Pt Div](pt_div.md) | Divides one PyTorch tensor by another element-wise. | -| [Pt Floor Div](pt_floor_divide.md) | Performs element-wise floor division on two PyTorch tensors. | -| [Pt Mul](pt_mul.md) | Multiplies two PyTorch tensors element-wise. | -| [Pt Pow](pt_pow.md) | Raises one PyTorch tensor to the power of another element-wise. | -| [Pt Remainder](pt_remainder.md) | Computes the element-wise remainder of division between two PyTorch tensors. | -| [Pt Sub](pt_sub.md) | Subtracts one PyTorch tensor from another. | -## PyTorch wrapper - Bitwise operations -| Node | Description | -| --- | --- | -| [Pt Bitwise And](pt_bitwise_and.md) | Performs a bitwise AND operation on two PyTorch tensors element-wise. | -| [Pt Bitwise Left Shift](pt_bitwise_left_shift.md) | Performs a bitwise left shift operation on two PyTorch tensors element-wise. | -| [Pt Bitwise Not](pt_bitwise_not.md) | Performs a bitwise NOT operation on a PyTorch tensor element-wise. | -| [Pt Bitwise Or](pt_bitwise_or.md) | Performs a bitwise OR operation on two PyTorch tensors element-wise. | -| [Pt Bitwise Right Shift](pt_bitwise_right_shift.md) | Performs a bitwise right shift operation on two PyTorch tensors element-wise. | -| [Pt Bitwise Xor](pt_bitwise_xor.md) | Performs a bitwise XOR operation on two PyTorch tensors element-wise. | -## PyTorch wrapper - Comparison operations -| Node | Description | -| --- | --- | -| [Pt Eq](pt_eq.md) | Tests whether two PyTorch tensors are equal element-wise. | -| [Pt Ge](pt_ge.md) | Tests whether elements in the first PyTorch tensor are greater than or equal to the corresponding elements in the second tensor. | -| [Pt Gt](pt_gt.md) | Tests whether elements in the first PyTorch tensor are greater than the corresponding elements in the second tensor. | -| [Pt Le](pt_le.md) | Tests whether elements in the first PyTorch tensor are less than or equal to the corresponding elements in the second tensor. | -| [Pt Lt](pt_lt.md) | Tests whether elements in the first PyTorch tensor are less than the corresponding elements in the second tensor. | -| [Pt Ne](pt_ne.md) | Tests whether two PyTorch tensors are not equal element-wise. | -## PyTorch wrapper - Image processing -| Node | Description | -| --- | --- | -| [Pt Crop](pt_crop.md) | Crops a PyTorch tensor to the specified size. The input tensor must have a shape of (c, h, w) or (b, c, h, w). | -| [Pt From Image](pt_from_image.md) | Casts an Image tensor as a PyTorch tensor. | -| [Pt From Image Transpose](pt_from_image_transpose.md) | Casts an image tensor to a PyTorch tensor and transposes it from (H, W, C) to (C, H, W). For rank-4 inputs, the batch axis remains unchanged. | -| [Pt Interpolate By Scale Factor](pt_interpolate_by_scale_factor.md) | Resizes a PyTorch tensor using interpolation by scale factor. The input tensor must have a shape of (c, h, w) or (b, c, h, w). | -| [Pt Interpolate To Size](pt_interpolate_to_size.md) | Resizes a PyTorch tensor using interpolation. The input tensor must have a shape of (c, h, w) or (b, c, h, w). | -| [Pt Pad](pt_pad.md) | Pads a PyTorch tensor to the specified size. Padded area will be black. The input tensor must have a shape of (c, h, w) or (b, c, h, w). | -| [Pt To Image](pt_to_image.md) | Casts a PyTorch tensor as an Image tensor. | -| [Pt To Image Transpose](pt_to_image_transpose.md) | Casts a PyTorch tensor as an Image tensor and transposes it from (C, H, W) to (H, W, C). For rank-4 inputs, the batch axis remains unchanged. | -## PyTorch wrapper - Indexing and Slicing Operations -| Node | Description | -| --- | --- | -| [Pt Gather](pt_gather.md) | Generates a tensor based on the index tensor using PyTorch's `gather` function. | -| [Pt Index Select](pt_index_select.md) | Extracts elements from the input tensor along a specified dimension using an index tensor. | -| [Pt Masked Select](pt_masked_select.md) | Extracts elements from the input tensor whose corresponding value in `masked_tens` is `True`. | -| [Pt Scatter](pt_scatter.md) | Generates a new tensor by replacing values at specified positions using an index tensor. | -| [Pt Where](pt_where.md) | Generates a new tensor by selecting values based on a condition tensor. | -## PyTorch wrapper - Logical operations -| Node | Description | -| --- | --- | -| [Pt Logical And](pt_logical_and.md) | Performs a logical AND operation on two PyTorch tensors element-wise. | -| [Pt Logical Not](pt_logical_not.md) | Performs a logical NOT operation on a PyTorch tensor element-wise. | -| [Pt Logical Or](pt_logical_or.md) | Performs a logical OR operation on two PyTorch tensors element-wise. | -| [Pt Logical Xor](pt_logical_xor.md) | Performs a logical XOR operation on two PyTorch tensors element-wise. | -## PyTorch wrapper - Math operations -| Node | Description | -| --- | --- | -| [Pt Abs](pt_abs.md) | Computes the absolute value of each element in a PyTorch tensor. | -| [Pt Acos](pt_acos.md) | Computes the arccosine (inverse cosine) of a PyTorch tensor element-wise. | -| [Pt Asin](pt_asin.md) | Computes the arcsine (inverse sine) of a PyTorch tensor element-wise. | -| [Pt Atan](pt_atan.md) | Computes the arc tangent (inverse tangent) of a PyTorch tensor element-wise. | -| [Pt Cos](pt_cos.md) | Computes the cosine of a PyTorch tensor element-wise. | -| [Pt Cosh](pt_cosh.md) | Computes the hyperbolic cosine of a PyTorch tensor element-wise. | -| [Pt Exp](pt_exp.md) | Performs an exponential operation on a PyTorch tensor element-wise. | -| [Pt Log](pt_log.md) | Computes the natural logarithm (log base e) of a PyTorch tensor element-wise. | -| [Pt Neg](pt_neg.md) | Computes the negation of each element in a PyTorch tensor. | -| [Pt Sin](pt_sin.md) | Computes the sine of a PyTorch tensor element-wise. | -| [Pt Sinh](pt_sinh.md) | Computes the hyperbolic sine of a PyTorch tensor element-wise. | -| [Pt Sqrt](pt_sqrt.md) | Computes the square root of each element in a PyTorch tensor. | -| [Pt Tan](pt_tan.md) | Computes the tangent of a PyTorch tensor element-wise. | -| [Pt Tanh](pt_tanh.md) | Computes the hyperbolic tangent of a PyTorch tensor element-wise. | -## PyTorch wrapper - Matrix operations -| Node | Description | -| --- | --- | -| [Pt Bmm](pt_bmm.md) | Performs batched matrix multiplication on two 3D PyTorch tensors. | -| [Pt Einsum](pt_einsum.md) | Performs Tensor operations specified in the Einstein summation equation. | -| [Pt Mat Mul](pt_matmul.md) | Performs matrix multiplication on two PyTorch tensors. | -| [Pt Mm](pt_mm.md) | Performs 2D matrix multiplication on two PyTorch tensors. | -## PyTorch wrapper - Reduction operation & Summary statistics -| Node | Description | -| --- | --- | -| [Pt Argmax](pt_argmax.md) | Computes the indices of the maximum values of a PyTorch tensor along the specified dimension(s). | -| [Pt Argmin](pt_argmin.md) | Computes the indices of the minimum values of a PyTorch tensor along the specified dimension(s). | -| [Pt Max](pt_max.md) | Computes the maximum values of a PyTorch tensor along the specified dimension(s). | -| [Pt Mean](pt_mean.md) | Computes the mean of a PyTorch tensor along the specified dimension(s). | -| [Pt Median](pt_median.md) | Computes the median of a PyTorch tensor along the specified dimension(s). | -| [Pt Min](pt_min.md) | Computes the minimum values of a PyTorch tensor along the specified dimension(s). | -| [Pt Prod](pt_prod.md) | Computes the product of a PyTorch tensor along the specified dimension(s). | -| [Pt Std](pt_std.md) | Computes the standard deviation of a PyTorch tensor along the specified dimension(s). | -| [Pt Sum](pt_sum.md) | Computes the sum of a PyTorch tensor along the specified dimension(s). | -| [Pt Var](pt_var.md) | Computes the variance of a PyTorch tensor along the specified dimension(s). | -## PyTorch wrapper - Size object support -| Node | Description | -| --- | --- | -| [Pt Size](pt_size.md) | Extracts the PyTorch Size object of a PyTorch tensor using the size() method. | -| [Pt Size Create](pt_size_create.md) | Creates a PyTorch Size using values entered in the text field. | -| [Pt Size To Numpy](pt_size_to_numpy.md) | Converts PyTorch Size object to NumPy ndarray. | -| [Pt Size To String](pt_size_to_string.md) | Converts PyTorch Size object to a Python string. | -## PyTorch wrapper - Tensor creation -| Node | Description | -| --- | --- | -| [Pt Arange](pt_arange.md) | Creates a PyTorch tensor using `torch.arange` with the specified start, end, and step values. | -| [Pt Bool Create](pt_bool_create.md) | Creates a PyTorch tensor of dtype bool from True or False values entered as a list in the text field. | -| [Pt Float Create](pt_float_create.md) | Creates a PyTorch tensor with 32-bit floating point precision | -| [Pt From Latent](pt_from_latent.md) | Casts a latent tensor as a PyTorch tensor. | -| [Pt From Numpy](pt_from_numpy.md) | Converts a NumPy ndarray to a PyTorch tensor while preserving its data type. | -| [Pt Full](pt_full.md) | Creates a PyTorch tensor filled with a specified value using the size entered in the text field. | -| [Pt Int Create](pt_int_create.md) | Creates a PyTorch tensor with 32-bit integer | -| [Pt Linspace](pt_linspace.md) | Creates a PyTorch tensor using `torch.linspace` with the specified start, end, and steps values. | -| [Pt Ones](pt_ones.md) | Creates a PyTorch tensor of ones using the size entered in the text field. | -| [Pt Rand](pt_rand.md) | Creates a PyTorch tensor with values sampled from a uniform distribution | -| [Pt Rand Int](pt_rand_int.md) | Creates a PyTorch tensor filled with random integers within a specified range using the size entered in the text field. | -| [Pt Randn](pt_randn.md) | Creates a PyTorch tensor with values sampled from a standard normal distribution (mean=0, std=1) | -| [Pt Zeros](pt_zeros.md) | Creates a PyTorch tensor of zeros using the size entered in the text field. | -## PyTorch wrapper - Tensor data conversion -| Node | Description | -| --- | --- | -| [Pt To Latent](pt_to_latent.md) | Casts a PyTorch tensor as a latent tensor. | -| [Pt To Numpy](pt_to_numpy.md) | Converts PyTorch tensor to NumPy ndarray. | -| [Pt To Rgb Tensors](pt_to_rgb_tensors.md) | Splits a PyTorch tensor into R, G, and B tensors. | -## PyTorch wrapper - Training -| Node | Description | -| --- | --- | -| [Pt Data Loader](pt_data_loader.md) | Loads data from a dataset node and creates a PyTorch DataLoader. | -| [Pt Evaluate Classification Model](pt_evaluate_classification_model.md) | Performs inference on test data and computes evaluation metrics. | -| [Pt Load Model](pt_load_model.md) | A wrapper class for saving a PyTorch model. | -| [Pt Predict Classification Model](pt_predict_classification_model.md) | Performs inference on input data. | -| [Pt Train Classification Model](pt_train_classification_model.md) | Trains a classification model using a given dataset, optimizer, and number of epochs. | -| [Ptn Conv Model](ptn_conv_model.md) | A convolutional model consisting of multiple convolutional layers. | -| [Ptn Linear Model](ptn_linear_model.md) | A linear model consisting of dense layers. | -| [Pto Adam](pto_adam.md) | Instantiates the Adam optimizer. | -| [Ptv Dataset](ptv_dataset.md) | A Torchvision Dataset class wrapper. | -| [Ptv Dataset Loader](ptv_dataset_loader.md) | A node to combine the dataset and data loader into a single node. | -| [Ptv Image Folder Dataset](ptv_image_folder_dataset.md) | A Torchvision ImageFolder Dataset class wrapper. | -| [Ptv Transforms Resize](ptv_transforms_resize.md) | Resizes and transforms elements of dataset to PyTorch tensors. | -| [Ptv Transforms To Tensor](ptv_transforms_to_tensor.md) | Transforms elements of dataset to PyTorch tensors. | -## PyTorch wrapper - Transform -| Node | Description | -| --- | --- | -| [Pt Flatten](pt_flatten.md) | Flattens a PyTorch tensor into a 1D tensor. | -| [Pt Permute](pt_permute.md) | Permutes the dimensions of a PyTorch tensor according to the specified order. | -| [Pt Reshape](pt_reshape.md) | Reshapes a PyTorch tensor into a specified shape using `torch.reshape()`. | -| [Pt Squeeze](pt_squeeze.md) | Removes a dimension at the specified position in the input tensor if it is of size 1. | -| [Pt Unsqueeze](pt_unsqueeze.md) | Adds a singleton dimension at the specified position in the input tensor. | -| [Pt View](pt_view.md) | Reshapes a PyTorch tensor into a specified shape using `torch.view()`. | ## Python wrapper | Node | Description | | --- | --- | diff --git a/docs/reference/pt_abs.md b/docs/reference/pt_abs.md deleted file mode 100644 index 2565442..0000000 --- a/docs/reference/pt_abs.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Abs -Computes the absolute value of each element in a PyTorch tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_acos.md b/docs/reference/pt_acos.md deleted file mode 100644 index 6df37ca..0000000 --- a/docs/reference/pt_acos.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Acos -Computes the arccosine (inverse cosine) of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_add.md b/docs/reference/pt_add.md deleted file mode 100644 index 070bfd0..0000000 --- a/docs/reference/pt_add.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Add -Adds two PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_arange.md b/docs/reference/pt_arange.md deleted file mode 100644 index 3a5e325..0000000 --- a/docs/reference/pt_arange.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Arange -Creates a PyTorch tensor using `torch.arange` with the specified start, end, and step values. - -The values are parsed from string inputs and converted to numeric types. This allows users to specify -tensor range values in text fields. The function also ensures proper dtype selection. - -## Input -| Name | Data type | -|---|---| -| start | String | -| end | String | -| step | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_argmax.md b/docs/reference/pt_argmax.md deleted file mode 100644 index 239bffc..0000000 --- a/docs/reference/pt_argmax.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Argmax -Computes the indices of the maximum values of a PyTorch tensor along the specified dimension(s). - -Specify the dimension in the `dim` field using an integer as shown below: -``` -0 -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_argmin.md b/docs/reference/pt_argmin.md deleted file mode 100644 index d08c285..0000000 --- a/docs/reference/pt_argmin.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Argmin -Computes the indices of the minimum values of a PyTorch tensor along the specified dimension(s). - -Specify the dimension in the `dim` field using an integer as shown below: -``` -0 -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_asin.md b/docs/reference/pt_asin.md deleted file mode 100644 index 8700137..0000000 --- a/docs/reference/pt_asin.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Asin -Computes the arcsine (inverse sine) of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_atan.md b/docs/reference/pt_atan.md deleted file mode 100644 index d745a09..0000000 --- a/docs/reference/pt_atan.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Atan -Computes the arc tangent (inverse tangent) of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_and.md b/docs/reference/pt_bitwise_and.md deleted file mode 100644 index 3678455..0000000 --- a/docs/reference/pt_bitwise_and.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bitwise And -Performs a bitwise AND operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_left_shift.md b/docs/reference/pt_bitwise_left_shift.md deleted file mode 100644 index 17ef621..0000000 --- a/docs/reference/pt_bitwise_left_shift.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bitwise Left Shift -Performs a bitwise left shift operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_not.md b/docs/reference/pt_bitwise_not.md deleted file mode 100644 index fd0080f..0000000 --- a/docs/reference/pt_bitwise_not.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Bitwise Not -Performs a bitwise NOT operation on a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_or.md b/docs/reference/pt_bitwise_or.md deleted file mode 100644 index 2bea79d..0000000 --- a/docs/reference/pt_bitwise_or.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bitwise Or -Performs a bitwise OR operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_right_shift.md b/docs/reference/pt_bitwise_right_shift.md deleted file mode 100644 index b206a8f..0000000 --- a/docs/reference/pt_bitwise_right_shift.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bitwise Right Shift -Performs a bitwise right shift operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bitwise_xor.md b/docs/reference/pt_bitwise_xor.md deleted file mode 100644 index 4074bb6..0000000 --- a/docs/reference/pt_bitwise_xor.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bitwise Xor -Performs a bitwise XOR operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Bitwise operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bmm.md b/docs/reference/pt_bmm.md deleted file mode 100644 index 151f974..0000000 --- a/docs/reference/pt_bmm.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Bmm -Performs batched matrix multiplication on two 3D PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Matrix operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_bool_create.md b/docs/reference/pt_bool_create.md deleted file mode 100644 index e342555..0000000 --- a/docs/reference/pt_bool_create.md +++ /dev/null @@ -1,22 +0,0 @@ -# Pt Bool Create -Creates a PyTorch tensor of dtype bool from True or False values entered as a list in the text field. -For example, entering: -``` -[True, False, False] -``` -will create a 1D boolean tensor. - -## Input -| Name | Data type | -|---|---| -| data | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_cos.md b/docs/reference/pt_cos.md deleted file mode 100644 index d180b87..0000000 --- a/docs/reference/pt_cos.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Cos -Computes the cosine of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_cosh.md b/docs/reference/pt_cosh.md deleted file mode 100644 index 9e3b309..0000000 --- a/docs/reference/pt_cosh.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Cosh -Computes the hyperbolic cosine of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_crop.md b/docs/reference/pt_crop.md deleted file mode 100644 index 44ed92b..0000000 --- a/docs/reference/pt_crop.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Crop -Crops a PyTorch tensor to the specified size. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - -In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - -This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| height | Int | -| width | Int | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_data_loader.md b/docs/reference/pt_data_loader.md deleted file mode 100644 index 2ae51c8..0000000 --- a/docs/reference/pt_data_loader.md +++ /dev/null @@ -1,29 +0,0 @@ -# Pt Data Loader -Loads data from a dataset node and creates a PyTorch DataLoader. - -**dataset** -Connect a PtvDataset node that provides the dataset. - -**batch size** -Specifies the number of samples per batch. - -**shuffle** -If True, shuffles the dataset before each epoch. - -## Input -| Name | Data type | -|---|---| -| dataset | Ptvdataset | -| batch_size | Int | -| shuffle | Boolean | -| parameters | String | - -## Output -| Data type | -|---| -| Ptdataloader | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_div.md b/docs/reference/pt_div.md deleted file mode 100644 index 585cdb7..0000000 --- a/docs/reference/pt_div.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Div -Divides one PyTorch tensor by another element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_einsum.md b/docs/reference/pt_einsum.md deleted file mode 100644 index fa1fcda..0000000 --- a/docs/reference/pt_einsum.md +++ /dev/null @@ -1,26 +0,0 @@ -# Pt Einsum -Performs Tensor operations specified in the Einstein summation equation. - -Specify Einstein summation notation in the first socket. -Specify two tensors in tens_a, tens_b. If you specify the third tensor, specify in tens_c. -Otherwise, leave the socket unconnected. - -Sublist format is not supported. - -## Input -| Name | Data type | -|---|---| -| equation | String | -| tens_a | Tensor | -| tens_b | Tensor | -| tens_c | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Matrix operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_eq.md b/docs/reference/pt_eq.md deleted file mode 100644 index 9228fa7..0000000 --- a/docs/reference/pt_eq.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Eq -Tests whether two PyTorch tensors are equal element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_evaluate_classification_model.md b/docs/reference/pt_evaluate_classification_model.md deleted file mode 100644 index c78bce9..0000000 --- a/docs/reference/pt_evaluate_classification_model.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Evaluate Classification Model -Performs inference on test data and computes evaluation metrics. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| data_loader | Ptdataloader | -| use_gpu | Boolean | - -## Output -| Data type | -|---| -| Float | -| Float | -| Float | -| Float | -| Int | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_exp.md b/docs/reference/pt_exp.md deleted file mode 100644 index 8c4ffe0..0000000 --- a/docs/reference/pt_exp.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Exp -Performs an exponential operation on a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_flatten.md b/docs/reference/pt_flatten.md deleted file mode 100644 index 9c32483..0000000 --- a/docs/reference/pt_flatten.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Flatten -Flattens a PyTorch tensor into a 1D tensor. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_float_create.md b/docs/reference/pt_float_create.md deleted file mode 100644 index d84a389..0000000 --- a/docs/reference/pt_float_create.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Float Create -Creates a PyTorch tensor with 32-bit floating point precision -using values entered in the text field. - -## Input -| Name | Data type | -|---|---| -| data | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_floor_divide.md b/docs/reference/pt_floor_divide.md deleted file mode 100644 index 8f52b4f..0000000 --- a/docs/reference/pt_floor_divide.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Floor Div -Performs element-wise floor division on two PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_from_image.md b/docs/reference/pt_from_image.md deleted file mode 100644 index 75c6409..0000000 --- a/docs/reference/pt_from_image.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt From Image -Casts an Image tensor as a PyTorch tensor. - -## Input -| Name | Data type | -|---|---| -| image | Image | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_from_image_transpose.md b/docs/reference/pt_from_image_transpose.md deleted file mode 100644 index 767e5b9..0000000 --- a/docs/reference/pt_from_image_transpose.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt From Image Transpose -Casts an image tensor to a PyTorch tensor and transposes it from (H, W, C) to (C, H, W). For rank-4 inputs, the batch axis remains unchanged. - -## Input -| Name | Data type | -|---|---| -| image | Image | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_from_latent.md b/docs/reference/pt_from_latent.md deleted file mode 100644 index 5ecb5b3..0000000 --- a/docs/reference/pt_from_latent.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt From Latent -Casts a latent tensor as a PyTorch tensor. - -## Input -| Name | Data type | -|---|---| -| latent | Latent | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_from_numpy.md b/docs/reference/pt_from_numpy.md deleted file mode 100644 index 105284d..0000000 --- a/docs/reference/pt_from_numpy.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt From Numpy -Converts a NumPy ndarray to a PyTorch tensor while preserving its data type. - -## Input -| Name | Data type | -|---|---| -| array | Ndarray | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_full.md b/docs/reference/pt_full.md deleted file mode 100644 index df0a41b..0000000 --- a/docs/reference/pt_full.md +++ /dev/null @@ -1,21 +0,0 @@ -# Pt Full -Creates a PyTorch tensor filled with a specified value using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32 filled with 7, enter: -[2,3,96,32] for size and 7 for value. - -## Input -| Name | Data type | -|---|---| -| value | String | -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_gather.md b/docs/reference/pt_gather.md deleted file mode 100644 index 9da9410..0000000 --- a/docs/reference/pt_gather.md +++ /dev/null @@ -1,59 +0,0 @@ -# Pt Gather -Generates a tensor based on the index tensor using PyTorch's `gather` function. - -Specify the `dim` field using an integer to indicate the axis along which to gather elements. -Each input tensor element is selected based on the index tensor. - -For example, consider the following input tensor: -``` -[ [10, 20, 30, 40, 50], - [100, 200, 300, 400, 500]] -``` - -and the corresponding index tensor: - -``` -[ [0, 4, 3, 2, 0], - [4, 3, 0, 0, 0]] -``` - -If `dim = 0`, the function scans row-wise, treating each index value as a row index. -If `dim = 1`, it scans column-wise, interpreting each index value as a column index. - -Let's analyze the case where `dim = 1`: - -* Start at row 0, column 0. -* The index at this position is `index[0, 0] = 0`. -* PyTorch selects the value at position 0 from the array `[10, 20, 30, 40, 50]`, which is `10`. -* The result at this stage is: - ``` - [[10, ?, ?, ?, ?] - [?, ?, ?, ?, ?]] - ``` - -* Moving to column 1: `index[0, 1] = 4`. -* The value at index 4 in `[10, 20, 30, 40, 50]` is `50`. -* The updated result is: - ``` - [[10, 50, ?, ?, ?] - [?, ?, ?, ?, ?]] - ``` - -* Repeating this process for all elements constructs the final gathered tensor. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | Int | -| index | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Indexing and Slicing Operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_ge.md b/docs/reference/pt_ge.md deleted file mode 100644 index bd7b39c..0000000 --- a/docs/reference/pt_ge.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Ge -Tests whether elements in the first PyTorch tensor are greater than or equal to the corresponding elements in the second tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_gt.md b/docs/reference/pt_gt.md deleted file mode 100644 index 5401090..0000000 --- a/docs/reference/pt_gt.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Gt -Tests whether elements in the first PyTorch tensor are greater than the corresponding elements in the second tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_index_select.md b/docs/reference/pt_index_select.md deleted file mode 100644 index 09e6778..0000000 --- a/docs/reference/pt_index_select.md +++ /dev/null @@ -1,41 +0,0 @@ -# Pt Index Select -Extracts elements from the input tensor along a specified dimension using an index tensor. - -`dim` specifies the dimension along which the selection occurs. -* For example, for 2D tensors: -** If `dim=0`, `index` selects rows. -** If `dim=1`, `index` selects columns (for 2D tensors). - -`index` is a list of indices that will be converted into a tensor. - -Example: -``` -Input Tensor: -[[1, 2, 3], - [40, 50, 60], - [700, 800, 900]] - -index = "[0, 2]" -dim = 0 - -Output Tensor: -[[1, 2, 3], - [700, 800, 900]] -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | Int | -| index | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Indexing and Slicing Operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_int_create.md b/docs/reference/pt_int_create.md deleted file mode 100644 index 9f3d826..0000000 --- a/docs/reference/pt_int_create.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Int Create -Creates a PyTorch tensor with 32-bit integer -using values entered in the text field. - -## Input -| Name | Data type | -|---|---| -| data | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_interpolate_by_scale_factor.md b/docs/reference/pt_interpolate_by_scale_factor.md deleted file mode 100644 index ec781ac..0000000 --- a/docs/reference/pt_interpolate_by_scale_factor.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Interpolate By Scale Factor -Resizes a PyTorch tensor using interpolation by scale factor. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - -In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - -This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| scale_factor | Float | -| mode | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_interpolate_to_size.md b/docs/reference/pt_interpolate_to_size.md deleted file mode 100644 index acec38d..0000000 --- a/docs/reference/pt_interpolate_to_size.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Interpolate To Size -Resizes a PyTorch tensor using interpolation. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - -In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - -This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| height | Int | -| width | Int | -| mode | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_le.md b/docs/reference/pt_le.md deleted file mode 100644 index aee74d2..0000000 --- a/docs/reference/pt_le.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Le -Tests whether elements in the first PyTorch tensor are less than or equal to the corresponding elements in the second tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_linspace.md b/docs/reference/pt_linspace.md deleted file mode 100644 index df29f03..0000000 --- a/docs/reference/pt_linspace.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Linspace -Creates a PyTorch tensor using `torch.linspace` with the specified start, end, and steps values. - -The start and end values are parsed from string inputs and converted to a float. -The steps value is converted to an int. - -## Input -| Name | Data type | -|---|---| -| start | String | -| end | String | -| steps | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_load_model.md b/docs/reference/pt_load_model.md deleted file mode 100644 index 0466004..0000000 --- a/docs/reference/pt_load_model.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Load Model -A wrapper class for saving a PyTorch model. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| model_path | String | - -## Output -| Data type | -|---| -| Ptmodel | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_log.md b/docs/reference/pt_log.md deleted file mode 100644 index f15a101..0000000 --- a/docs/reference/pt_log.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Log -Computes the natural logarithm (log base e) of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_logical_and.md b/docs/reference/pt_logical_and.md deleted file mode 100644 index 10255b1..0000000 --- a/docs/reference/pt_logical_and.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Logical And -Performs a logical AND operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Logical operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_logical_not.md b/docs/reference/pt_logical_not.md deleted file mode 100644 index 66616e3..0000000 --- a/docs/reference/pt_logical_not.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Logical Not -Performs a logical NOT operation on a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Logical operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_logical_or.md b/docs/reference/pt_logical_or.md deleted file mode 100644 index 3519a38..0000000 --- a/docs/reference/pt_logical_or.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Logical Or -Performs a logical OR operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Logical operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_logical_xor.md b/docs/reference/pt_logical_xor.md deleted file mode 100644 index c67fe55..0000000 --- a/docs/reference/pt_logical_xor.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Logical Xor -Performs a logical XOR operation on two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Logical operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_lt.md b/docs/reference/pt_lt.md deleted file mode 100644 index b44c48b..0000000 --- a/docs/reference/pt_lt.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Lt -Tests whether elements in the first PyTorch tensor are less than the corresponding elements in the second tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_masked_select.md b/docs/reference/pt_masked_select.md deleted file mode 100644 index 80b9e15..0000000 --- a/docs/reference/pt_masked_select.md +++ /dev/null @@ -1,34 +0,0 @@ -# Pt Masked Select -Extracts elements from the input tensor whose corresponding value in `masked_tens` is `True`. - -Example: -``` -Input Tensor: -[[1, 2, 3], - [40, 50, 60], - [700, 800, 900]] - -Masked Tensor: -[[True, False, False], - [False, True, False], - [False, False, True]] - -Output Tensor: -[1, 50, 900] -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| masked_tens | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Indexing and Slicing Operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_matmul.md b/docs/reference/pt_matmul.md deleted file mode 100644 index 8536132..0000000 --- a/docs/reference/pt_matmul.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Mat Mul -Performs matrix multiplication on two PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Matrix operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_max.md b/docs/reference/pt_max.md deleted file mode 100644 index 1f8b497..0000000 --- a/docs/reference/pt_max.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Max -Computes the maximum values of a PyTorch tensor along the specified dimension(s). - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_mean.md b/docs/reference/pt_mean.md deleted file mode 100644 index e202099..0000000 --- a/docs/reference/pt_mean.md +++ /dev/null @@ -1,26 +0,0 @@ -# Pt Mean -Computes the mean of a PyTorch tensor along the specified dimension(s). - -This node supports only floating-point or complex tensors as input. - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_median.md b/docs/reference/pt_median.md deleted file mode 100644 index 1d698d9..0000000 --- a/docs/reference/pt_median.md +++ /dev/null @@ -1,29 +0,0 @@ -# Pt Median -Computes the median of a PyTorch tensor along the specified dimension(s). - -Specify the dimension(s) in the `dim` field using an integer as shown below: -``` -0 -``` -or -``` -1 -``` -Note that PtMedian calls torch.median(), which returns the lower of the two numbers when the true median falls between them. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_min.md b/docs/reference/pt_min.md deleted file mode 100644 index f0dc408..0000000 --- a/docs/reference/pt_min.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Min -Computes the minimum values of a PyTorch tensor along the specified dimension(s). - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_mm.md b/docs/reference/pt_mm.md deleted file mode 100644 index c6524b9..0000000 --- a/docs/reference/pt_mm.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Mm -Performs 2D matrix multiplication on two PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Matrix operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_mul.md b/docs/reference/pt_mul.md deleted file mode 100644 index cda34b4..0000000 --- a/docs/reference/pt_mul.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Mul -Multiplies two PyTorch tensors element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_ne.md b/docs/reference/pt_ne.md deleted file mode 100644 index 37e88c7..0000000 --- a/docs/reference/pt_ne.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Ne -Tests whether two PyTorch tensors are not equal element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Comparison operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_neg.md b/docs/reference/pt_neg.md deleted file mode 100644 index 23d9114..0000000 --- a/docs/reference/pt_neg.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Neg -Computes the negation of each element in a PyTorch tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_ones.md b/docs/reference/pt_ones.md deleted file mode 100644 index 5f42dc7..0000000 --- a/docs/reference/pt_ones.md +++ /dev/null @@ -1,20 +0,0 @@ -# Pt Ones -Creates a PyTorch tensor of ones using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: -[2,3,96,32] - -## Input -| Name | Data type | -|---|---| -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_pad.md b/docs/reference/pt_pad.md deleted file mode 100644 index 2353f26..0000000 --- a/docs/reference/pt_pad.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Pad -Pads a PyTorch tensor to the specified size. Padded area will be black. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - -In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - -This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| height | Int | -| width | Int | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_permute.md b/docs/reference/pt_permute.md deleted file mode 100644 index 8fa187f..0000000 --- a/docs/reference/pt_permute.md +++ /dev/null @@ -1,25 +0,0 @@ -# Pt Permute -Permutes the dimensions of a PyTorch tensor according to the specified order. -For example, if a tensor has shape (2, 3, 96, 32) and `new_axes="[0, 3, 1, 2]"`, -the output will have shape (2, 32, 3, 96). - -Specify the new axis order in the `new_axes` field using brackets, as shown below: -``` -[0, 3, 1, 2] -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| new_axes | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_pow.md b/docs/reference/pt_pow.md deleted file mode 100644 index 1d717bf..0000000 --- a/docs/reference/pt_pow.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Pow -Raises one PyTorch tensor to the power of another element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_predict_classification_model.md b/docs/reference/pt_predict_classification_model.md deleted file mode 100644 index 217f61a..0000000 --- a/docs/reference/pt_predict_classification_model.md +++ /dev/null @@ -1,22 +0,0 @@ -# Pt Predict Classification Model -Performs inference on input data. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| inputs | Tensor | -| class_id_to_name_map | Pydict | -| use_gpu | Boolean | - -## Output -| Data type | -|---| -| String | -| Int | -| Float | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_prod.md b/docs/reference/pt_prod.md deleted file mode 100644 index f7d2f37..0000000 --- a/docs/reference/pt_prod.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pt Prod -Computes the product of a PyTorch tensor along the specified dimension(s). - -Specify the dimension(s) in the `dim` field using an integer as shown below: -``` -0 -``` -or -``` -1 -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_rand.md b/docs/reference/pt_rand.md deleted file mode 100644 index 34ccd58..0000000 --- a/docs/reference/pt_rand.md +++ /dev/null @@ -1,21 +0,0 @@ -# Pt Rand -Creates a PyTorch tensor with values sampled from a uniform distribution -using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: -[2,3,96,32] - -## Input -| Name | Data type | -|---|---| -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_rand_int.md b/docs/reference/pt_rand_int.md deleted file mode 100644 index 16552cd..0000000 --- a/docs/reference/pt_rand_int.md +++ /dev/null @@ -1,22 +0,0 @@ -# Pt Rand Int -Creates a PyTorch tensor filled with random integers within a specified range using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32 with random integers in the range [0, 10), -enter [2,3,96,32] for size, 0 for min_value, and 10 for max_value. - -## Input -| Name | Data type | -|---|---| -| min_value | Int | -| max_value | Int | -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_randn.md b/docs/reference/pt_randn.md deleted file mode 100644 index 8c2057b..0000000 --- a/docs/reference/pt_randn.md +++ /dev/null @@ -1,21 +0,0 @@ -# Pt Randn -Creates a PyTorch tensor with values sampled from a standard normal distribution (mean=0, std=1) -using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: -[2,3,96,32] - -## Input -| Name | Data type | -|---|---| -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_remainder.md b/docs/reference/pt_remainder.md deleted file mode 100644 index e4f68e6..0000000 --- a/docs/reference/pt_remainder.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Remainder -Computes the element-wise remainder of division between two PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_reshape.md b/docs/reference/pt_reshape.md deleted file mode 100644 index fecad29..0000000 --- a/docs/reference/pt_reshape.md +++ /dev/null @@ -1,27 +0,0 @@ -# Pt Reshape -Reshapes a PyTorch tensor into a specified shape using `torch.reshape()`. -The total number of elements must remain unchanged. - -For example, if a tensor has shape (2, 3, 4), and `new_shape="[6, 4]"`, -the output will have shape (6, 4). - -Use -1 to automatically infer a dimension, e.g.: -``` -[2, -1] -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| new_shape | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_save_model.md b/docs/reference/pt_save_model.md deleted file mode 100644 index da2d30c..0000000 --- a/docs/reference/pt_save_model.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Save Model -A wrapper class for saving a PyTorch model. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| model_path | String | - -## Output -| Data type | -|---| -| String | - -
-Category: IO - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_scatter.md b/docs/reference/pt_scatter.md deleted file mode 100644 index 719ea0c..0000000 --- a/docs/reference/pt_scatter.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Scatter -Generates a new tensor by replacing values at specified positions using an index tensor. - -* Target tensor (tens): Some of whose values are replaced. -* Source tensor (src): Values from this tensor replace a part or whole of the target tensor. -* Index tensor (index): Specifies the positions in the target tensor for replacement. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | Int | -| index | String | -| src | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Indexing and Slicing Operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_show_size.md b/docs/reference/pt_show_size.md deleted file mode 100644 index 8830fb1..0000000 --- a/docs/reference/pt_show_size.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Show Size -Displays PyTorch Size object as a string. - -## Input -| Name | Data type | -|---|---| -| size | Ptsize | - -## Output -| Data type | -|---| -| String | - -
-Category: Display data - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_show_text.md b/docs/reference/pt_show_text.md deleted file mode 100644 index 40e397d..0000000 --- a/docs/reference/pt_show_text.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Show Text -Displays PyTorch tensor as a string. Note that the tensor is partially printed out when -the tensor contains more elements than the threshold set internally. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| String | - -
-Category: Display data - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_sin.md b/docs/reference/pt_sin.md deleted file mode 100644 index 158065b..0000000 --- a/docs/reference/pt_sin.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Sin -Computes the sine of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_sinh.md b/docs/reference/pt_sinh.md deleted file mode 100644 index 755828f..0000000 --- a/docs/reference/pt_sinh.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Sinh -Computes the hyperbolic sine of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_size.md b/docs/reference/pt_size.md deleted file mode 100644 index a879754..0000000 --- a/docs/reference/pt_size.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Size -Extracts the PyTorch Size object of a PyTorch tensor using the size() method. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Ptsize | - -
-Category: PyTorch wrapper - Size object support - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_size_create.md b/docs/reference/pt_size_create.md deleted file mode 100644 index 8aee4ab..0000000 --- a/docs/reference/pt_size_create.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Size Create -Creates a PyTorch Size using values entered in the text field. - -## Input -| Name | Data type | -|---|---| -| data | String | - -## Output -| Data type | -|---| -| Ptsize | - -
-Category: PyTorch wrapper - Size object support - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_size_to_numpy.md b/docs/reference/pt_size_to_numpy.md deleted file mode 100644 index 784063d..0000000 --- a/docs/reference/pt_size_to_numpy.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Size To Numpy -Converts PyTorch Size object to NumPy ndarray. - -## Input -| Name | Data type | -|---|---| -| sz | Ptsize | - -## Output -| Data type | -|---| -| Ndarray | - -
-Category: PyTorch wrapper - Size object support - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_size_to_string.md b/docs/reference/pt_size_to_string.md deleted file mode 100644 index 2e94aaa..0000000 --- a/docs/reference/pt_size_to_string.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Size To String -Converts PyTorch Size object to a Python string. - -## Input -| Name | Data type | -|---|---| -| sz | Ptsize | - -## Output -| Data type | -|---| -| String | - -
-Category: PyTorch wrapper - Size object support - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_sqrt.md b/docs/reference/pt_sqrt.md deleted file mode 100644 index 0b6165c..0000000 --- a/docs/reference/pt_sqrt.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Sqrt -Computes the square root of each element in a PyTorch tensor. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_squeeze.md b/docs/reference/pt_squeeze.md deleted file mode 100644 index b11c993..0000000 --- a/docs/reference/pt_squeeze.md +++ /dev/null @@ -1,20 +0,0 @@ -# Pt Squeeze -Removes a dimension at the specified position in the input tensor if it is of size 1. - -Specifying a tuple of dimensions is not supported yet. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | Int | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_std.md b/docs/reference/pt_std.md deleted file mode 100644 index 16ebc9b..0000000 --- a/docs/reference/pt_std.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pt Std -Computes the standard deviation of a PyTorch tensor along the specified dimension(s). - -Specify 1 to use Bessel's correction (N-1) for sample standard deviation. -Specify 0 to compute population standard deviation. - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| correction | Int | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_sub.md b/docs/reference/pt_sub.md deleted file mode 100644 index 827a938..0000000 --- a/docs/reference/pt_sub.md +++ /dev/null @@ -1,18 +0,0 @@ -# Pt Sub -Subtracts one PyTorch tensor from another. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | -| tens_b | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Arithmetic operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_sum.md b/docs/reference/pt_sum.md deleted file mode 100644 index 99608c8..0000000 --- a/docs/reference/pt_sum.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Sum -Computes the sum of a PyTorch tensor along the specified dimension(s). - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_tan.md b/docs/reference/pt_tan.md deleted file mode 100644 index a05b3a5..0000000 --- a/docs/reference/pt_tan.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Tan -Computes the tangent of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_tanh.md b/docs/reference/pt_tanh.md deleted file mode 100644 index eff2b90..0000000 --- a/docs/reference/pt_tanh.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt Tanh -Computes the hyperbolic tangent of a PyTorch tensor element-wise. - -## Input -| Name | Data type | -|---|---| -| tens_a | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Math operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_to_image.md b/docs/reference/pt_to_image.md deleted file mode 100644 index a5f86e8..0000000 --- a/docs/reference/pt_to_image.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt To Image -Casts a PyTorch tensor as an Image tensor. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Image | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_to_image_transpose.md b/docs/reference/pt_to_image_transpose.md deleted file mode 100644 index 21af352..0000000 --- a/docs/reference/pt_to_image_transpose.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt To Image Transpose -Casts a PyTorch tensor as an Image tensor and transposes it from (C, H, W) to (H, W, C). For rank-4 inputs, the batch axis remains unchanged. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Image | - -
-Category: PyTorch wrapper - Image processing - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_to_latent.md b/docs/reference/pt_to_latent.md deleted file mode 100644 index 9a1278c..0000000 --- a/docs/reference/pt_to_latent.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt To Latent -Casts a PyTorch tensor as a latent tensor. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Latent | - -
-Category: PyTorch wrapper - Tensor data conversion - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_to_numpy.md b/docs/reference/pt_to_numpy.md deleted file mode 100644 index 47821d3..0000000 --- a/docs/reference/pt_to_numpy.md +++ /dev/null @@ -1,17 +0,0 @@ -# Pt To Numpy -Converts PyTorch tensor to NumPy ndarray. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Ndarray | - -
-Category: PyTorch wrapper - Tensor data conversion - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_to_rgb_tensors.md b/docs/reference/pt_to_rgb_tensors.md deleted file mode 100644 index aff0b37..0000000 --- a/docs/reference/pt_to_rgb_tensors.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pt To Rgb Tensors -Splits a PyTorch tensor into R, G, and B tensors. - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | - -## Output -| Data type | -|---| -| Tensor | -| Tensor | -| Tensor | - -
-Category: PyTorch wrapper - Tensor data conversion - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_train_classification_model.md b/docs/reference/pt_train_classification_model.md deleted file mode 100644 index 1ceaac6..0000000 --- a/docs/reference/pt_train_classification_model.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pt Train Classification Model -Trains a classification model using a given dataset, optimizer, and number of epochs. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| train_loader | Ptdataloader | -| optimizer | Ptoptimizer | -| epochs | Int | -| use_gpu | Boolean | -| val_loader | Ptdataloader | - -## Output -| Data type | -|---| -| Ptmodel | -| Tensor | -| Tensor | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_unsqueeze.md b/docs/reference/pt_unsqueeze.md deleted file mode 100644 index 96bc5b1..0000000 --- a/docs/reference/pt_unsqueeze.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pt Unsqueeze -Adds a singleton dimension at the specified position in the input tensor. -For example, if a tensor has shape (3, 4) and `dim=1`, the output will have shape (3, 1, 4). - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| dim | Int | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_var.md b/docs/reference/pt_var.md deleted file mode 100644 index 383af73..0000000 --- a/docs/reference/pt_var.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pt Var -Computes the variance of a PyTorch tensor along the specified dimension(s). - -Specify 1 to use Bessel's correction (N-1) for sample variance. -Specify 0 to compute population variance. - -Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: -``` -0, [0], or (1, 2) -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| correction | Int | -| dim | String | -| keepdim | Boolean | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Reduction operation & Summary statistics - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_view.md b/docs/reference/pt_view.md deleted file mode 100644 index d366f3e..0000000 --- a/docs/reference/pt_view.md +++ /dev/null @@ -1,27 +0,0 @@ -# Pt View -Reshapes a PyTorch tensor into a specified shape using `torch.view()`. -The total number of elements must remain unchanged. - -For example, if a tensor has shape (2, 3, 4), and `new_shape="[6, 4]"`, -the output will have shape (6, 4). - -Use -1 to automatically infer a dimension, e.g.: -``` -[2, -1] -``` - -## Input -| Name | Data type | -|---|---| -| tens | Tensor | -| new_shape | String | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Transform - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_where.md b/docs/reference/pt_where.md deleted file mode 100644 index b10ead9..0000000 --- a/docs/reference/pt_where.md +++ /dev/null @@ -1,23 +0,0 @@ -# Pt Where -Generates a new tensor by selecting values based on a condition tensor. - -* `condition_tens` (torch.Tensor): Boolean tensor that determines which values are selected. -* `true_tens` (torch.Tensor): Values to use where the condition is `True`. -* `false_tens` (torch.Tensor): Values to use where the condition is `False`. - -## Input -| Name | Data type | -|---|---| -| condition_tens | Tensor | -| true_tens | Tensor | -| false_tens | Tensor | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Indexing and Slicing Operations - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pt_zeros.md b/docs/reference/pt_zeros.md deleted file mode 100644 index 7019740..0000000 --- a/docs/reference/pt_zeros.md +++ /dev/null @@ -1,20 +0,0 @@ -# Pt Zeros -Creates a PyTorch tensor of zeros using the size entered in the text field. -For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: -[2,3,96,32] - -## Input -| Name | Data type | -|---|---| -| size | String | -| data_type | | - -## Output -| Data type | -|---| -| Tensor | - -
-Category: PyTorch wrapper - Tensor creation - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptn_conv_model.md b/docs/reference/ptn_conv_model.md deleted file mode 100644 index d881ea0..0000000 --- a/docs/reference/ptn_conv_model.md +++ /dev/null @@ -1,45 +0,0 @@ -# Ptn Conv Model -A convolutional model consisting of multiple convolutional layers. - -### Fields: -- `input_dim`: A string representing the input dimensions in the format "(C,H,W)". - Example: `"(3,28,28)"` for a 3-channel 28x28 image. - -- `penultimate_dim`: An integer specifying the number of features before the output layer. If you specify 0, the number is computed internally. - Default: `0` - -- `output_dim`: An integer specifying the number of output features, which should match the number of target classes in classification. - Default: `10`, Min: `1`, Max: `1e6`. - -- `channel_list`: A string representing a Python list of integers specifying the number of channels per layer excluding the channel for the input (e.g. 3 for the color image). - Example: `"[32,64,128,256,512]"`. - -- `kernel_size_list`: A string representing a Python list of kernel sizes per layer. - Example: `"[3,3,3,3,1]"`. - -- `padding_list`: A string representing a Python list of padding values per layer. - Example: `"[1,1,1,1,0]"`. - -- `downsample_list`: A string representing a Python list of boolean values indicating whether to downsample at each layer. - Example: `"[True,True,True,True,False]"`. - -## Input -| Name | Data type | -|---|---| -| input_dim | String | -| penultimate_dim | Int | -| output_dim | Int | -| channel_list | String | -| kernel_size_list | String | -| padding_list | String | -| downsample_list | String | - -## Output -| Data type | -|---| -| Ptmodel | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptn_linear_model.md b/docs/reference/ptn_linear_model.md deleted file mode 100644 index a9788fa..0000000 --- a/docs/reference/ptn_linear_model.md +++ /dev/null @@ -1,35 +0,0 @@ -# Ptn Linear Model -A linear model consisting of dense layers. - -### Fields: -- `dim_list`: A string representing a Python list of layer dimensions. - It should contain the input dimension for the first layer and the output dimensions - for all layers. - - Example for a two-layer network: - - Input data: 784 - - Layer 1: 784 → 128 - - Layer 2: 128 → 10 - - Specify `"[784,128,10]"` - -- `bias_list`: A string representing a Python list of bias usage (True/False) per layer. - Example: "[True,False]" - -- `num_layers`: The number of layers in the model. - -## Input -| Name | Data type | -|---|---| -| dim_list | String | -| bias_list | String | -| num_layers | Int | - -## Output -| Data type | -|---| -| Ptmodel | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pto_adam.md b/docs/reference/pto_adam.md deleted file mode 100644 index 257420e..0000000 --- a/docs/reference/pto_adam.md +++ /dev/null @@ -1,20 +0,0 @@ -# Pto Adam -Instantiates the Adam optimizer. - -## Input -| Name | Data type | -|---|---| -| model | Ptmodel | -| learning_rate | Float | -| beta1 | Float | -| beta2 | Float | - -## Output -| Data type | -|---| -| Ptoptimizer | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptv_dataset.md b/docs/reference/ptv_dataset.md deleted file mode 100644 index 1258c76..0000000 --- a/docs/reference/ptv_dataset.md +++ /dev/null @@ -1,51 +0,0 @@ -# Ptv Dataset -A Torchvision Dataset class wrapper. - -Parameters - -**name** - Specify a dataset class name such as MNIST, FashionMNIST in string. - This will be converted to a dataset class internally. - -**download** - Set to True if you want to download. - -**root** - Specify the root directory of the downloaded dataset relative to the - dataset directory of this extension, or specify the absolute path. - If you leave as a blank, the dataset will be downloaded under the `datasets` directory - of this extension. - -**transform** - Data transforms e.g. transform to PyTorch tensor, normalize image. - Plug in the PTV Transforms node that contains Torchvision Transforms functionality. - -**parameters** - Specify other parameters in Python dict format. - For example, if you want to set Train parameter to True to download the train set, specify: - ``` - {"train": True} - ``` - or if you want to download the test set, specify: - ``` - {"train": False} - ``` - -## Input -| Name | Data type | -|---|---| -| name | String | -| download | Boolean | -| root | String | -| transform | Ptvtransform | -| parameters | String | - -## Output -| Data type | -|---| -| Ptvdataset | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptv_dataset_loader.md b/docs/reference/ptv_dataset_loader.md deleted file mode 100644 index ee13ac5..0000000 --- a/docs/reference/ptv_dataset_loader.md +++ /dev/null @@ -1,60 +0,0 @@ -# Ptv Dataset Loader -A node to combine the dataset and data loader into a single node. - -Transform is internally called to convert input data to PyTorch tensors. - -Parameters - -**name** - Specify the dataset class name such as MNIST, FashionMNIST in string. - This will be converted to a dataset class internally. - -**download** - Set to True if you want to download. - -**root** - Specify the root directory of the downloaded dataset relative to the - dataset directory of this extension, or specify the absolute path. - If you leave as a blank, the dataset will be downloaded under the `datasets` directory - of this extension. - -**batch_size** - The number of samples per batch. - -**shuffle** - If True, shuffles the dataset before each epoch. - -**dataset parameters** - Specify other parameters in Python dict format. - For example, if you want to set Train parameter to True to download the train set, specify: - ``` - {"train": True} - ``` - or if you want to download the test set, specify: - ``` - {"train": False} - ``` - -**load parameters** - Additional parameters in Python dictionary format. - -## Input -| Name | Data type | -|---|---| -| name | String | -| download | Boolean | -| root | String | -| batch_size | Int | -| shuffle | Boolean | -| dataset_parameters | String | -| load_parameters | String | - -## Output -| Data type | -|---| -| Ptdataloader | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptv_image_folder_dataset.md b/docs/reference/ptv_image_folder_dataset.md deleted file mode 100644 index b973b55..0000000 --- a/docs/reference/ptv_image_folder_dataset.md +++ /dev/null @@ -1,28 +0,0 @@ -# Ptv Image Folder Dataset -A Torchvision ImageFolder Dataset class wrapper. - -Parameters - -**root** - Specify the root directory that contains subdirectories which of which contains images for each class. - The subdirectory name needs to be named after each class. - -**transform** - Data transforms e.g. transform to PyTorch tensor, normalize image. - Plug in the PTV Transforms node that contains Torchvision Transforms functionality. - -## Input -| Name | Data type | -|---|---| -| root | String | -| transform | Ptvtransform | - -## Output -| Data type | -|---| -| Ptvdataset | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptv_transforms_resize.md b/docs/reference/ptv_transforms_resize.md deleted file mode 100644 index 159626f..0000000 --- a/docs/reference/ptv_transforms_resize.md +++ /dev/null @@ -1,18 +0,0 @@ -# Ptv Transforms Resize -Resizes and transforms elements of dataset to PyTorch tensors. - -## Input -| Name | Data type | -|---|---| -| height | Int | -| width | Int | - -## Output -| Data type | -|---| -| Ptvtransform | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/ptv_transforms_to_tensor.md b/docs/reference/ptv_transforms_to_tensor.md deleted file mode 100644 index e1ca095..0000000 --- a/docs/reference/ptv_transforms_to_tensor.md +++ /dev/null @@ -1,12 +0,0 @@ -# Ptv Transforms To Tensor -Transforms elements of dataset to PyTorch tensors. - -## Output -| Data type | -|---| -| Ptvtransform | - -
-Category: PyTorch wrapper - Training - -ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/examples/workflows/dog_cat_classification_eval_model.json b/examples/workflows/dog_cat_classification_eval_model.json deleted file mode 100644 index aff7eff..0000000 --- a/examples/workflows/dog_cat_classification_eval_model.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":54,"last_link_id":67,"nodes":[{"id":49,"type":"PtDataLoader","pos":[2664.0126953125,2004.834716796875],"size":[308.1214599609375,135.3099822998047],"flags":{},"order":5,"mode":0,"inputs":[{"name":"dataset","type":"PTVDATASET","link":64}],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[65],"slot_index":0}],"properties":{"Node name for S&R":"PtDataLoader"},"widgets_values":[8,false,"{\"num_workers\":1}"]},{"id":50,"type":"PtvImageFolderDataset","pos":[2324.53857421875,2006.695068359375],"size":[315,58],"flags":{},"order":3,"mode":0,"inputs":[{"name":"transform","type":"PTVTRANSFORM","link":67,"shape":7}],"outputs":[{"name":"PTVDATASET","type":"PTVDATASET","links":[64],"slot_index":0}],"properties":{"Node name for S&R":"PtvImageFolderDataset"},"widgets_values":["/container/transfer/datasets/dog_and_cat/dog_and_cat/val/"]},{"id":53,"type":"PtvTransformsResize","pos":[1959.0155029296875,2007.09521484375],"size":[315,82],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PTVTRANSFORM","type":"PTVTRANSFORM","links":[67],"slot_index":0}],"properties":{"Node name for S&R":"PtvTransformsResize"},"widgets_values":[256,256]},{"id":48,"type":"PtnConvModel","pos":[2666.497314453125,1718.6485595703125],"size":[315,202],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[62],"slot_index":0}],"properties":{"Node name for S&R":"PtnConvModel"},"widgets_values":["(3,256,256)",0,2,"[32,64,128,256,512]","[3,3,3,3,3]","[1,1,1,1,1]","[True,True,True,True,True]"]},{"id":47,"type":"PtEvaluateClassificationModel","pos":[3073.28466796875,1998.2191162109375],"size":[268.79998779296875,148.22767639160156],"flags":{},"order":6,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":55},{"name":"data_loader","type":"PTDATALOADER","link":65}],"outputs":[{"name":"accuracy","type":"FLOAT","links":[66],"slot_index":0},{"name":"precision","type":"FLOAT","links":[58],"slot_index":1},{"name":"recall","type":"FLOAT","links":[59],"slot_index":2},{"name":"f1","type":"FLOAT","links":[60],"slot_index":3},{"name":"num_samples","type":"INT","links":[61],"slot_index":4}],"properties":{"Node name for S&R":"PtEvaluateClassificationModel"},"widgets_values":[true]},{"id":33,"type":"CDAShowInt","pos":[3507.768310546875,2136.57861328125],"size":[210,79.09933471679688],"flags":{},"order":11,"mode":0,"inputs":[{"name":"int_scalar","type":"INT","link":61,"widget":{"name":"int_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Num Samples","properties":{"Node name for S&R":"CDAShowInt"},"widgets_values":[0,"300"]},{"id":30,"type":"CDAShowFloat","pos":[3507.768310546875,1986.105712890625],"size":[210,76],"flags":{},"order":9,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":59,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Recall","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9"]},{"id":31,"type":"CDAShowFloat","pos":[3768.4755859375,1980.9920654296875],"size":[210,76],"flags":{},"order":10,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":60,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"F1","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.8997817469155049"]},{"id":29,"type":"CDAShowFloat","pos":[3768.4755859375,1834.9833984375],"size":[210,76],"flags":{},"order":8,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":58,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Precision","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9035150645624104"]},{"id":52,"type":"CDAShowFloat","pos":[3507.768310546875,1834.7109375],"size":[210,76],"flags":{},"order":7,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":66,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Accuracy","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9"]},{"id":23,"type":"PtLoadModel","pos":[3075.703369140625,1723.319580078125],"size":[261.13433837890625,74.19380950927734],"flags":{},"order":4,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":62}],"outputs":[{"name":"model","type":"PTMODEL","links":[55],"slot_index":0}],"properties":{"Node name for S&R":"PtLoadModel"},"widgets_values":["dog_cat.pt"]},{"id":54,"type":"MarkdownNote","pos":[2328.715576171875,1839.947509765625],"size":[313.0150451660156,99.62860870361328],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load val data\nYou need set the root field to point to the **val** directory of the dataset you downloaded."],"color":"#322","bgcolor":"#533"}],"links":[[55,23,0,47,0,"PTMODEL"],[58,47,1,29,0,"FLOAT"],[59,47,2,30,0,"FLOAT"],[60,47,3,31,0,"FLOAT"],[61,47,4,33,0,"INT"],[62,48,0,23,0,"PTMODEL"],[64,50,0,49,0,"PTVDATASET"],[65,49,0,47,1,"PTDATALOADER"],[66,47,0,52,0,"FLOAT"],[67,53,0,50,0,"PTVTRANSFORM"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.34289106510190753,"offset":[-1247.259007394664,-447.540790015054]},"node_versions":{"data-analysis":"db92cda5f5a1e611e15ca6f2531ff8585a5607a5"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/dog_cat_classification_prediction.json b/examples/workflows/dog_cat_classification_prediction.json deleted file mode 100644 index 187c32a..0000000 --- a/examples/workflows/dog_cat_classification_prediction.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":74,"last_link_id":97,"nodes":[{"id":73,"type":"PtFromImageTranspose","pos":[1488.2567138671875,1628.712646484375],"size":[289.79998779296875,26],"flags":{},"order":4,"mode":0,"inputs":[{"name":"image","type":"IMAGE","link":95}],"outputs":[{"name":"TENSOR","type":"TENSOR","links":[96],"slot_index":0}],"properties":{"Node name for S&R":"PtFromImageTranspose"}},{"id":74,"type":"PtInterpolateToSize","pos":[1801.049560546875,1628.712646484375],"size":[315,106],"flags":{},"order":5,"mode":0,"inputs":[{"name":"tens","type":"TENSOR","link":96}],"outputs":[{"name":"TENSOR","type":"TENSOR","links":[97],"slot_index":0}],"properties":{"Node name for S&R":"PtInterpolateToSize"},"widgets_values":[256,256,"nearest-exact"]},{"id":69,"type":"PtSqueeze","pos":[2206.266357421875,1639.8197021484375],"size":[210,60.5162467956543],"flags":{},"order":6,"mode":0,"inputs":[{"name":"tens","type":"TENSOR","link":97}],"outputs":[{"name":"TENSOR","type":"TENSOR","links":[88],"slot_index":0}],"properties":{"Node name for S&R":"PtSqueeze"},"widgets_values":[0]},{"id":55,"type":"PtPredictClassificationModel","pos":[2482.278564453125,1626.3341064453125],"size":[405.5999755859375,98],"flags":{},"order":7,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":70},{"name":"inputs","type":"TENSOR","link":88},{"name":"class_id_to_name_map","type":"PYDICT","link":69}],"outputs":[{"name":"class_name","type":"STRING","links":[74],"slot_index":0},{"name":"class_id","type":"INT","links":null},{"name":"probability","type":"FLOAT","links":[93],"slot_index":2}],"properties":{"Node name for S&R":"PtPredictClassificationModel"},"widgets_values":[true]},{"id":56,"type":"PyStringToDict","pos":[2206.266357421875,1774.539306640625],"size":[210,81.30076599121094],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PYDICT","type":"PYDICT","links":[69],"slot_index":0}],"properties":{"Node name for S&R":"PyStringToDict"},"widgets_values":["{0:\"cat\", 1:\"dog\"}"]},{"id":60,"type":"PandasShowText","pos":[2970.7451171875,1629.65576171875],"size":[221.17684936523438,76],"flags":{},"order":8,"mode":0,"inputs":[{"name":"text","type":"STRING","link":74,"widget":{"name":"text"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowText"},"widgets_values":["","cat"]},{"id":72,"type":"CDAShowFloat","pos":[2976.763916015625,1770.6387939453125],"size":[210,76],"flags":{},"order":9,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":93,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9118371605873108"]},{"id":23,"type":"PtLoadModel","pos":[2206.266357421875,1482.663330078125],"size":[210,75.45188903808594],"flags":{},"order":3,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":62}],"outputs":[{"name":"model","type":"PTMODEL","links":[70],"slot_index":0}],"properties":{"Node name for S&R":"PtLoadModel"},"widgets_values":["dog_cat.pt"]},{"id":57,"type":"LoadImage","pos":[1135.1787109375,1628.712646484375],"size":[315,314],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[95],"slot_index":0},{"name":"MASK","type":"MASK","links":null}],"properties":{"Node name for S&R":"LoadImage"},"widgets_values":["cat.jpg","image"]},{"id":48,"type":"PtnConvModel","pos":[1801.049560546875,1306.3406982421875],"size":[315,202],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[62],"slot_index":0}],"properties":{"Node name for S&R":"PtnConvModel"},"widgets_values":["(3,256,256)",0,2,"[32,64,128,256,512]","[3,3,3,3,3]","[1,1,1,1,1]","[True,True,True,True,True]"]}],"links":[[62,48,0,23,0,"PTMODEL"],[69,56,0,55,2,"PYDICT"],[70,23,0,55,0,"PTMODEL"],[74,55,0,60,0,"STRING"],[88,69,0,55,1,"TENSOR"],[93,55,2,72,0,"FLOAT"],[95,57,0,73,0,"IMAGE"],[96,73,0,74,0,"TENSOR"],[97,74,0,69,0,"TENSOR"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6339486400897979,"offset":[-879.509850098028,-1085.7559202042573]},"node_versions":{"data-analysis":"fd6fa94b931cd094ce5766852f5914d7291cb464","comfy-core":"v0.3.10-40-gd0f3752"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/dog_cat_classification_train_model.json b/examples/workflows/dog_cat_classification_train_model.json deleted file mode 100644 index 706b774..0000000 --- a/examples/workflows/dog_cat_classification_train_model.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":86,"last_link_id":95,"nodes":[{"id":11,"type":"PtoAdam","pos":[3106.311767578125,1425.00830078125],"size":[265.8851013183594,108.32855224609375],"flags":{},"order":16,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":89}],"outputs":[{"name":"PTOPTIMIZER","type":"PTOPTIMIZER","links":[68],"slot_index":0}],"properties":{"Node name for S&R":"PtoAdam"},"widgets_values":[0.0001,0.9,0.999]},{"id":72,"type":"PtDataLoader","pos":[2583.5888671875,1626.235595703125],"size":[400,200],"flags":{},"order":20,"mode":0,"inputs":[{"name":"dataset","type":"PTVDATASET","link":86}],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[87],"slot_index":0}],"properties":{"Node name for S&R":"PtDataLoader"},"widgets_values":[8,true,"{\"num_workers\":1}"]},{"id":19,"type":"PtSaveModel","pos":[3464.489501953125,1694.661376953125],"size":[280.30267333984375,68.31287384033203],"flags":{},"order":23,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":71}],"outputs":[{"name":"model full path","type":"STRING","links":[70],"slot_index":0}],"properties":{"Node name for S&R":"PtSaveModel"},"widgets_values":["dog_cat.pt"]},{"id":74,"type":"PtvImageFolderDataset","pos":[2228.7578125,1923.7598876953125],"size":[315,58],"flags":{},"order":18,"mode":0,"inputs":[{"name":"transform","type":"PTVTRANSFORM","link":95,"shape":7}],"outputs":[{"name":"PTVDATASET","type":"PTVDATASET","links":[91],"slot_index":0}],"properties":{"Node name for S&R":"PtvImageFolderDataset"},"widgets_values":["/container/transfer/datasets/dog_and_cat/dog_and_cat/val/"]},{"id":71,"type":"PtnConvModel","pos":[2607.428955078125,1271.409912109375],"size":[315,202],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[88,89],"slot_index":0}],"properties":{"Node name for S&R":"PtnConvModel"},"widgets_values":["(3,256,256)",0,2,"[32,64,128,256,512]","[3,3,3,3,3]","[1,1,1,1,1]","[True,True,True,True,True]"]},{"id":53,"type":"MarkdownNote","pos":[2219.2607421875,1485.9119873046875],"size":[310.71795654296875,94.28345489501953],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load train data\nYou need set the root field to point to the **train** directory of the dataset you downloaded."],"color":"#322","bgcolor":"#533"},{"id":76,"type":"MarkdownNote","pos":[2014.2506103515625,926.4641723632812],"size":[436.95391845703125,69.52714538574219],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Dog Cat Classification Model Training"],"color":"#432","bgcolor":"#653"},{"id":78,"type":"PtvTransformsResize","pos":[1820.2008056640625,1781.384521484375],"size":[315,82],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"PTVTRANSFORM","type":"PTVTRANSFORM","links":[94,95],"slot_index":0}],"properties":{"Node name for S&R":"PtvTransformsResize"},"widgets_values":[256,256]},{"id":52,"type":"MarkdownNote","pos":[2605.098876953125,1119.3177490234375],"size":[308.6709289550781,100.76033782958984],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Model set up\n\nNo need to edit this node unless you are familiar with machine learning"],"color":"#232","bgcolor":"#353"},{"id":79,"type":"MarkdownNote","pos":[1816.8997802734375,1627.8802490234375],"size":[317.4327697753906,98.5698471069336],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Dataset transformation\n\nNo need to edit this node unless you are familiar with machine learning. This resizes input data to 256px x 256px."],"color":"#232","bgcolor":"#353"},{"id":75,"type":"PtDataLoader","pos":[2588.29736328125,1922.6170654296875],"size":[400,200],"flags":{},"order":21,"mode":0,"inputs":[{"name":"dataset","type":"PTVDATASET","link":91}],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[93],"slot_index":0}],"properties":{"Node name for S&R":"PtDataLoader"},"widgets_values":[8,false,"{\"num_workers\":1}"]},{"id":51,"type":"PandasShowText","pos":[3845.79296875,1686.58056640625],"size":[499.0397033691406,76],"flags":{},"order":26,"mode":0,"inputs":[{"name":"text","type":"STRING","link":70,"widget":{"name":"text"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowText"},"widgets_values":["","/home/dockeruser/comfy/ComfyUI/custom_nodes/data-analysis/models/dog_cat.pt"]},{"id":58,"type":"PandasCreateFromTensor","pos":[3487.738037109375,2425.4267578125],"size":[315,26],"flags":{},"order":25,"mode":0,"inputs":[{"name":"tens","type":"TENSOR","link":73}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[75],"slot_index":0}],"properties":{"Node name for S&R":"PandasCreateFromTensor"},"widgets_values":[]},{"id":64,"type":"PandasCreateFromTensor","pos":[3844.351806640625,2508.688720703125],"size":[315,26],"flags":{},"order":19,"mode":0,"inputs":[{"name":"tens","type":"TENSOR","link":78}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[77],"slot_index":0}],"properties":{"Node name for S&R":"PandasCreateFromTensor"},"widgets_values":[]},{"id":65,"type":"PandasHorizontalConcat","pos":[4218.2119140625,2380.0498046875],"size":[315,78],"flags":{},"order":28,"mode":0,"inputs":[{"name":"a_dataframe","type":"DATAFRAME","link":79},{"name":"b_dataframe","type":"DATAFRAME","link":77}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[80,81],"slot_index":0}],"properties":{"Node name for S&R":"PandasHorizontalConcat"},"widgets_values":[true]},{"id":61,"type":"PandasRenameAdvanced","pos":[4608.04443359375,2380.0498046875],"size":[238.48175048828125,131.16506958007812],"flags":{},"order":30,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":81}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[82],"slot_index":0}],"properties":{"Node name for S&R":"PandasRenameAdvanced"},"widgets_values":["columns","{0:\"train\",1:\"val\",2:\"epoch\"}"]},{"id":60,"type":"SNSLine","pos":[4918.4609375,2380.0498046875],"size":[315,250],"flags":{},"order":31,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":82}],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[84],"slot_index":0}],"properties":{"Node name for S&R":"SNSLine"},"widgets_values":["epoch","train,val","Loss","Epoch","Cross entropy loss","train,val",true,"",""]},{"id":68,"type":"SaveImage","pos":[5326.560546875,2380.0498046875],"size":[315,270],"flags":{},"order":32,"mode":0,"inputs":[{"name":"images","type":"IMAGE","link":84}],"outputs":[],"properties":{"Node name for S&R":"SaveImage"},"widgets_values":["dog_cat_train"]},{"id":57,"type":"PandasCreateFromTensor","pos":[3483.9892578125,2346.20166015625],"size":[315,26],"flags":{},"order":24,"mode":0,"inputs":[{"name":"tens","type":"TENSOR","link":72}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[74],"slot_index":0}],"properties":{"Node name for S&R":"PandasCreateFromTensor"},"widgets_values":[]},{"id":83,"type":"MarkdownNote","pos":[2943.528564453125,925.8107299804688],"size":[336.614990234375,70.34814453125],"flags":{},"order":6,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["## Yellow nodes may require adjustment"],"color":"#432","bgcolor":"#653"},{"id":80,"type":"MarkdownNote","pos":[3106.311767578125,1250.9371337890625],"size":[257.6202392578125,106.56401062011719],"flags":{},"order":7,"mode":2,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Optimizer\nYou may need to adjust the learning rate but starts with the number below."],"color":"#432","bgcolor":"#653"},{"id":50,"type":"PtTrainClassificationModel","pos":[3106.311767578125,1663.041748046875],"size":[265.619873046875,145.1302490234375],"flags":{},"order":22,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":88},{"name":"train_loader","type":"PTDATALOADER","link":87},{"name":"optimizer","type":"PTOPTIMIZER","link":68},{"name":"val_loader","type":"PTDATALOADER","link":93,"shape":7}],"outputs":[{"name":"Model","type":"PTMODEL","links":[71],"slot_index":0},{"name":"train loss","type":"TENSOR","links":[72],"slot_index":1},{"name":"val loss","type":"TENSOR","links":[73],"slot_index":2}],"properties":{"Node name for S&R":"PtTrainClassificationModel"},"widgets_values":[20,true]},{"id":84,"type":"MarkdownNote","pos":[2596.4189453125,2210.809326171875],"size":[387.0498352050781,100.52718353271484],"flags":{},"order":8,"mode":2,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Data loading\nIf GPU throws OOM, make the batch_size smaller."],"color":"#432","bgcolor":"#653"},{"id":82,"type":"MarkdownNote","pos":[2944.823486328125,805.5132446289062],"size":[326.2669677734375,67.76112365722656],"flags":{},"order":9,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["## Red nodes require editing"],"color":"#322","bgcolor":"#533"},{"id":77,"type":"MarkdownNote","pos":[2230.19091796875,2034.1849365234375],"size":[313.0150451660156,99.62860870361328],"flags":{},"order":10,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load val data\nYou need set the root field to point to the **val** directory of the dataset you downloaded."],"color":"#322","bgcolor":"#533"},{"id":62,"type":"PtArange","pos":[3481.524169921875,2515.711669921875],"size":[315,130],"flags":{},"order":11,"mode":0,"inputs":[],"outputs":[{"name":"TENSOR","type":"TENSOR","links":[78],"slot_index":0}],"properties":{"Node name for S&R":"PtArange"},"widgets_values":["0","20","","float32"],"color":"#432","bgcolor":"#653"},{"id":55,"type":"MarkdownNote","pos":[3106.311767578125,1861.1396484375],"size":[265.81390380859375,103.27005767822266],"flags":{},"order":12,"mode":2,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Train\nYou may need to adjust epochs but start with 20."],"color":"#432","bgcolor":"#653"},{"id":85,"type":"MarkdownNote","pos":[3485.391357421875,2688.060791015625],"size":[304.5123596191406,100.34938049316406],"flags":{},"order":13,"mode":2,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Update \"end\" field\nIf you change the epochs, change the end field to match."],"color":"#432","bgcolor":"#653"},{"id":66,"type":"PandasShowDataFrame","pos":[4215.47265625,2533.793701171875],"size":[315.237060546875,414.686279296875],"flags":{},"order":29,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":80}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" 0 1 2\n0 0.686489 0.680127 0.0\n1 0.621646 0.571015 1.0\n2 0.499781 0.471638 2.0\n3 0.382664 0.404523 3.0\n4 0.289659 0.329657 4.0\n5 0.224341 0.292451 5.0\n6 0.160335 0.291596 6.0\n7 0.110199 0.321644 7.0\n8 0.091624 0.270642 8.0\n9 0.052231 0.221975 9.0\n10 0.048100 0.281967 10.0\n11 0.022782 0.289861 11.0\n12 0.013045 0.305584 12.0\n13 0.013724 0.307031 13.0\n14 0.020037 0.271379 14.0\n15 0.031278 0.310788 15.0\n16 0.012516 0.338837 16.0\n17 0.017392 0.298860 17.0\n18 0.001674 0.316514 18.0\n19 0.000855 0.358205 19.0"]},{"id":59,"type":"PandasHorizontalConcat","pos":[3849.372802734375,2380.0498046875],"size":[315,78],"flags":{},"order":27,"mode":0,"inputs":[{"name":"a_dataframe","type":"DATAFRAME","link":74},{"name":"b_dataframe","type":"DATAFRAME","link":75}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[79],"slot_index":0}],"properties":{"Node name for S&R":"PandasHorizontalConcat"},"widgets_values":[true]},{"id":86,"type":"MarkdownNote","pos":[3453.1630859375,2150.53857421875],"size":[1160.256103515625,64.83271026611328],"flags":{},"order":14,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# This area is to show how training went. Initially, it's OK if you don't understand the meaning."],"color":"#232","bgcolor":"#353"},{"id":69,"type":"PtvImageFolderDataset","pos":[2220.0927734375,1629.250732421875],"size":[315,58],"flags":{},"order":17,"mode":0,"inputs":[{"name":"transform","type":"PTVTRANSFORM","link":94,"shape":7}],"outputs":[{"name":"PTVDATASET","type":"PTVDATASET","links":[86],"slot_index":0}],"properties":{"Node name for S&R":"PtvImageFolderDataset"},"widgets_values":["/container/transfer/datasets/dog_and_cat/dog_and_cat/train/"]},{"id":56,"type":"MarkdownNote","pos":[3464.170166015625,1519.1202392578125],"size":[285.6708679199219,95.45172882080078],"flags":{},"order":15,"mode":2,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Save model\nUpdate the model path if needed.\nThis is saved under custom_nodes/data-analysis/models"],"color":"#432","bgcolor":"#653"}],"links":[[68,11,0,50,2,"PTOPTIMIZER"],[70,19,0,51,0,"STRING"],[71,50,0,19,0,"PTMODEL"],[72,50,1,57,0,"TENSOR"],[73,50,2,58,0,"TENSOR"],[74,57,0,59,0,"DATAFRAME"],[75,58,0,59,1,"DATAFRAME"],[77,64,0,65,1,"DATAFRAME"],[78,62,0,64,0,"TENSOR"],[79,59,0,65,0,"DATAFRAME"],[80,65,0,66,0,"DATAFRAME"],[81,65,0,61,0,"DATAFRAME"],[82,61,0,60,0,"DATAFRAME"],[84,60,0,68,0,"IMAGE"],[86,69,0,72,0,"PTVDATASET"],[87,72,0,50,1,"PTDATALOADER"],[88,71,0,50,0,"PTMODEL"],[89,71,0,11,0,"PTMODEL"],[91,74,0,75,0,"PTVDATASET"],[93,75,0,50,3,"PTDATALOADER"],[94,78,0,69,0,"PTVTRANSFORM"],[95,78,0,74,0,"PTVTRANSFORM"]],"groups":[{"id":1,"title":"Training metrics","bounding":[3447.499755859375,2242.806884765625,2284.0107421875,790.1612548828125],"color":"#8A8","font_size":24,"flags":{}}],"config":{},"extra":{"ds":{"scale":0.3736662716119983,"offset":[-975.7677617863449,-688.047741909445]},"node_versions":{"data-analysis":"db92cda5f5a1e611e15ca6f2531ff8585a5607a5","comfy-core":"v0.3.10-40-gd0f3752"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/fashion_mnist_eval.json b/examples/workflows/fashion_mnist_eval.json deleted file mode 100644 index c9e452e..0000000 --- a/examples/workflows/fashion_mnist_eval.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":47,"last_link_id":61,"nodes":[{"id":47,"type":"PtEvaluateClassificationModel","pos":[3243.2138671875,1887.3746337890625],"size":[403.1999816894531,138],"flags":{},"order":3,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":55},{"name":"data_loader","type":"PTDATALOADER","link":56}],"outputs":[{"name":"accuracy","type":"FLOAT","links":[57],"slot_index":0},{"name":"precision","type":"FLOAT","links":[58],"slot_index":1},{"name":"recall","type":"FLOAT","links":[59],"slot_index":2},{"name":"f1","type":"FLOAT","links":[60],"slot_index":3},{"name":"num_samples","type":"INT","links":[61],"slot_index":4}],"properties":{"Node name for S&R":"PtEvaluateClassificationModel"},"widgets_values":[true]},{"id":22,"type":"PtnLinearModel","pos":[2886.657958984375,1718.1610107421875],"size":[264.3730163574219,109.75016021728516],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[24],"slot_index":0}],"properties":{"Node name for S&R":"PtnLinearModel"},"widgets_values":["[784,180,42,10]","[False,False,False]",3]},{"id":33,"type":"CDAShowInt","pos":[3716.05078125,2073.464111328125],"size":[210,79.09933471679688],"flags":{},"order":8,"mode":0,"inputs":[{"name":"int_scalar","type":"INT","link":61,"widget":{"name":"int_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Num Samples","properties":{"Node name for S&R":"CDAShowInt"},"widgets_values":[0,"10000"]},{"id":31,"type":"CDAShowFloat","pos":[3937.552490234375,1932.3660888671875],"size":[210,76],"flags":{},"order":7,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":60,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"F1","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.8705378412983575"]},{"id":29,"type":"CDAShowFloat","pos":[3937.552490234375,1808.5174560546875],"size":[210,76],"flags":{},"order":5,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":58,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Precision","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.8721685257742706"]},{"id":30,"type":"CDAShowFloat","pos":[3716.05078125,1932.3660888671875],"size":[210,76],"flags":{},"order":6,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":59,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Recall","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.8715999999999999"]},{"id":28,"type":"CDAShowFloat","pos":[3716.05078125,1808.5174560546875],"size":[210,76],"flags":{},"order":4,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":57,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Accuracy","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.8716"]},{"id":46,"type":"PtvDatasetLoader","pos":[2884.05078125,1908.8636474609375],"size":[266.8697814941406,246],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[56],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,false,"{\"train\":False}","{\"num_workers\":1}"]},{"id":23,"type":"PtLoadModel","pos":[3243.927978515625,1718.1610107421875],"size":[397.5032653808594,67.37537384033203],"flags":{},"order":2,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":24}],"outputs":[{"name":"model","type":"PTMODEL","links":[55],"slot_index":0}],"properties":{"Node name for S&R":"PtLoadModel"},"widgets_values":["fashion_mnist_ep5.pt"]}],"links":[[24,22,0,23,0,"PTMODEL"],[55,23,0,47,0,"PTMODEL"],[56,46,0,47,1,"PTDATALOADER"],[57,47,0,28,0,"FLOAT"],[58,47,1,29,0,"FLOAT"],[59,47,2,30,0,"FLOAT"],[60,47,3,31,0,"FLOAT"],[61,47,4,33,0,"INT"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.8888542618071794,"offset":[-2627.7528215343027,-1537.849355050907]},"node_versions":{"data-analysis":"dab52eaa403a5e9cdc546aca7f7d95e41ea0a943"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/fashion_mnist_eval_conv.json b/examples/workflows/fashion_mnist_eval_conv.json deleted file mode 100644 index fc3883d..0000000 --- a/examples/workflows/fashion_mnist_eval_conv.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":48,"last_link_id":62,"nodes":[{"id":47,"type":"PtEvaluateClassificationModel","pos":[3243.2138671875,1887.3746337890625],"size":[403.1999816894531,138],"flags":{},"order":3,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":55},{"name":"data_loader","type":"PTDATALOADER","link":56}],"outputs":[{"name":"accuracy","type":"FLOAT","links":[57],"slot_index":0},{"name":"precision","type":"FLOAT","links":[58],"slot_index":1},{"name":"recall","type":"FLOAT","links":[59],"slot_index":2},{"name":"f1","type":"FLOAT","links":[60],"slot_index":3},{"name":"num_samples","type":"INT","links":[61],"slot_index":4}],"properties":{"Node name for S&R":"PtEvaluateClassificationModel"},"widgets_values":[true]},{"id":33,"type":"CDAShowInt","pos":[3716.05078125,2073.464111328125],"size":[210,79.09933471679688],"flags":{},"order":8,"mode":0,"inputs":[{"name":"int_scalar","type":"INT","link":61,"widget":{"name":"int_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Num Samples","properties":{"Node name for S&R":"CDAShowInt"},"widgets_values":[0,"10000"]},{"id":31,"type":"CDAShowFloat","pos":[3937.552490234375,1932.3660888671875],"size":[210,76],"flags":{},"order":7,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":60,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"F1","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9085886169153918"]},{"id":29,"type":"CDAShowFloat","pos":[3937.552490234375,1808.5174560546875],"size":[210,76],"flags":{},"order":5,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":58,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Precision","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.9113484312788449"]},{"id":30,"type":"CDAShowFloat","pos":[3716.05078125,1932.3660888671875],"size":[210,76],"flags":{},"order":6,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":59,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Recall","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.908"]},{"id":28,"type":"CDAShowFloat","pos":[3716.05078125,1808.5174560546875],"size":[210,76],"flags":{},"order":4,"mode":0,"inputs":[{"name":"float_scalar","type":"FLOAT","link":57,"widget":{"name":"float_scalar"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"title":"Accuracy","properties":{"Node name for S&R":"CDAShowFloat"},"widgets_values":[0,"0.908"]},{"id":46,"type":"PtvDatasetLoader","pos":[2884.05078125,1908.8636474609375],"size":[266.8697814941406,246],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[56],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,false,"{\"train\":False}","{\"num_workers\":1}"]},{"id":48,"type":"PtnConvModel","pos":[2846.147216796875,1629.3045654296875],"size":[315,202],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[62],"slot_index":0}],"properties":{"Node name for S&R":"PtnConvModel"},"widgets_values":["(1,28,28)",0,10,"[32,64,128,256,512]","[3,3,3,3,1]","[1,1,1,1,0]","[True,True,True,True,False]"]},{"id":23,"type":"PtLoadModel","pos":[3243.927978515625,1718.1610107421875],"size":[397.5032653808594,67.37537384033203],"flags":{},"order":2,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":62}],"outputs":[{"name":"model","type":"PTMODEL","links":[55],"slot_index":0}],"properties":{"Node name for S&R":"PtLoadModel"},"widgets_values":["fashion_mnist_conv_ep5.pt"]}],"links":[[55,23,0,47,0,"PTMODEL"],[56,46,0,47,1,"PTDATALOADER"],[57,47,0,28,0,"FLOAT"],[58,47,1,29,0,"FLOAT"],[59,47,2,30,0,"FLOAT"],[60,47,3,31,0,"FLOAT"],[61,47,4,33,0,"INT"],[62,48,0,23,0,"PTMODEL"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.9652303192711613,"offset":[-2706.3348752184625,-1469.581964047439]},"node_versions":{"data-analysis":"11335e88b00ed3b4a5129f92d3d134854b6b4a92"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/fashion_mnist_train.json b/examples/workflows/fashion_mnist_train.json deleted file mode 100644 index c693a15..0000000 --- a/examples/workflows/fashion_mnist_train.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":56,"last_link_id":71,"nodes":[{"id":22,"type":"PtnLinearModel","pos":[2830.718017578125,1445.9212646484375],"size":[222.090087890625,128.31336975097656],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[22,65],"slot_index":0}],"properties":{"Node name for S&R":"PtnLinearModel"},"widgets_values":["[784,180,42,10]","[False,False,False]",3]},{"id":47,"type":"PtvDatasetLoader","pos":[2830.718017578125,1652.3197021484375],"size":[239.68125915527344,246],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[66],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,true,"{\"train\":True}","{\"num_workers\":1}"]},{"id":48,"type":"PtvDatasetLoader","pos":[2830.718017578125,1957.211181640625],"size":[239.68125915527344,246],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[67],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,false,"{\"train\":False}","{\"num_workers\":1}"]},{"id":50,"type":"PtTrainClassificationModel","pos":[3170.615478515625,1736.97705078125],"size":[243.70773315429688,142],"flags":{},"order":9,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":65},{"name":"train_loader","type":"PTDATALOADER","link":66},{"name":"optimizer","type":"PTOPTIMIZER","link":68},{"name":"val_loader","type":"PTDATALOADER","link":67,"shape":7}],"outputs":[{"name":"Model","type":"PTMODEL","links":[71],"slot_index":0},{"name":"train loss","type":"TENSOR","links":null},{"name":"val loss","type":"TENSOR","links":null}],"properties":{"Node name for S&R":"PtTrainClassificationModel"},"widgets_values":[5,true]},{"id":19,"type":"PtSaveModel","pos":[3464.489501953125,1694.661376953125],"size":[280.30267333984375,68.31287384033203],"flags":{},"order":10,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":71}],"outputs":[{"name":"model full path","type":"STRING","links":[70],"slot_index":0}],"properties":{"Node name for S&R":"PtSaveModel"},"widgets_values":["fashion_mnist_ep5.pt"]},{"id":54,"type":"MarkdownNote","pos":[2582.973388671875,1955.99560546875],"size":[210,58.94380569458008],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load val data"],"color":"#432","bgcolor":"#653"},{"id":53,"type":"MarkdownNote","pos":[2582.973388671875,1652.8607177734375],"size":[210,58.94380569458008],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load train data"],"color":"#432","bgcolor":"#653"},{"id":11,"type":"PtoAdam","pos":[3170.615478515625,1445.9212646484375],"size":[265.8851013183594,108.32855224609375],"flags":{},"order":8,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":22}],"outputs":[{"name":"PTOPTIMIZER","type":"PTOPTIMIZER","links":[68],"slot_index":0}],"properties":{"Node name for S&R":"PtoAdam"},"widgets_values":[0.001,0.9,0.999]},{"id":52,"type":"MarkdownNote","pos":[2582.973388671875,1445.9212646484375],"size":[210,58.94380569458008],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Define model"],"color":"#432","bgcolor":"#653"},{"id":55,"type":"MarkdownNote","pos":[3170.615478515625,1953.1151123046875],"size":[210,58.94380569458008],"flags":{},"order":6,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Train"],"color":"#432","bgcolor":"#653"},{"id":56,"type":"MarkdownNote","pos":[3468.277099609375,1806.20458984375],"size":[210,58.94380569458008],"flags":{},"order":7,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Save model"],"color":"#432","bgcolor":"#653"},{"id":51,"type":"PandasShowText","pos":[3469.39404296875,1921.830078125],"size":[576.9476318359375,81.15640258789062],"flags":{},"order":11,"mode":0,"inputs":[{"name":"text","type":"STRING","link":70,"widget":{"name":"text"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowText"},"widgets_values":["","/home/dockeruser/comfy/ComfyUI/custom_nodes/data-analysis/models/fashion_mnist_ep5.pt"]}],"links":[[22,22,0,11,0,"PTMODEL"],[65,22,0,50,0,"PTMODEL"],[66,47,0,50,1,"PTDATALOADER"],[67,48,0,50,3,"PTDATALOADER"],[68,11,0,50,2,"PTOPTIMIZER"],[70,19,0,51,0,"STRING"],[71,50,0,19,0,"PTMODEL"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.8678754334266201,"offset":[-2457.1876923760833,-1312.0857787454647]},"node_versions":{"data-analysis":"dab52eaa403a5e9cdc546aca7f7d95e41ea0a943"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/examples/workflows/fashion_mnist_train_conv.json b/examples/workflows/fashion_mnist_train_conv.json deleted file mode 100644 index c34d729..0000000 --- a/examples/workflows/fashion_mnist_train_conv.json +++ /dev/null @@ -1 +0,0 @@ -{"last_node_id":57,"last_link_id":73,"nodes":[{"id":50,"type":"PtTrainClassificationModel","pos":[3170.615478515625,1736.97705078125],"size":[243.70773315429688,142],"flags":{},"order":9,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":73},{"name":"train_loader","type":"PTDATALOADER","link":66},{"name":"optimizer","type":"PTOPTIMIZER","link":68},{"name":"val_loader","type":"PTDATALOADER","link":67,"shape":7}],"outputs":[{"name":"Model","type":"PTMODEL","links":[71],"slot_index":0},{"name":"train loss","type":"TENSOR","links":null},{"name":"val loss","type":"TENSOR","links":null}],"properties":{"Node name for S&R":"PtTrainClassificationModel"},"widgets_values":[5,true]},{"id":11,"type":"PtoAdam","pos":[3170.615478515625,1445.9212646484375],"size":[265.8851013183594,108.32855224609375],"flags":{},"order":8,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":72}],"outputs":[{"name":"PTOPTIMIZER","type":"PTOPTIMIZER","links":[68],"slot_index":0}],"properties":{"Node name for S&R":"PtoAdam"},"widgets_values":[0.001,0.9,0.999]},{"id":55,"type":"MarkdownNote","pos":[3170.615478515625,1953.1151123046875],"size":[210,58.94380569458008],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Train"],"color":"#432","bgcolor":"#653"},{"id":56,"type":"MarkdownNote","pos":[3468.277099609375,1806.20458984375],"size":[210,58.94380569458008],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Save model"],"color":"#432","bgcolor":"#653"},{"id":51,"type":"PandasShowText","pos":[3469.39404296875,1921.830078125],"size":[576.9476318359375,81.15640258789062],"flags":{},"order":11,"mode":0,"inputs":[{"name":"text","type":"STRING","link":70,"widget":{"name":"text"}}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowText"},"widgets_values":["","/home/dockeruser/comfy/ComfyUI/custom_nodes/data-analysis/models/fashion_mnist_conv_ep5.pt"]},{"id":53,"type":"MarkdownNote","pos":[2456.569091796875,1652.8607177734375],"size":[210,58.94380569458008],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load train data"],"color":"#432","bgcolor":"#653"},{"id":54,"type":"MarkdownNote","pos":[2456.569091796875,1961.218994140625],"size":[210,58.94380569458008],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Load val data"],"color":"#432","bgcolor":"#653"},{"id":52,"type":"MarkdownNote","pos":[2456.569091796875,1384.5592041015625],"size":[210,58.94380569458008],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["# Define model"],"color":"#432","bgcolor":"#653"},{"id":48,"type":"PtvDatasetLoader","pos":[2770.126708984375,1962.4345703125],"size":[309.6732482910156,246.00001525878906],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[67],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,false,"{\"train\":False}","{\"num_workers\":1}"]},{"id":47,"type":"PtvDatasetLoader","pos":[2770.126708984375,1649.1856689453125],"size":[314.89654541015625,246],"flags":{},"order":6,"mode":0,"inputs":[],"outputs":[{"name":"PTDATALOADER","type":"PTDATALOADER","links":[66],"slot_index":0}],"properties":{"Node name for S&R":"PtvDatasetLoader"},"widgets_values":["FashionMNIST",true,"",128,true,"{\"train\":True}","{\"num_workers\":1}"]},{"id":19,"type":"PtSaveModel","pos":[3464.489501953125,1694.661376953125],"size":[280.30267333984375,68.31287384033203],"flags":{},"order":10,"mode":0,"inputs":[{"name":"model","type":"PTMODEL","link":71}],"outputs":[{"name":"model full path","type":"STRING","links":[70],"slot_index":0}],"properties":{"Node name for S&R":"PtSaveModel"},"widgets_values":["fashion_mnist_conv_ep5.pt"]},{"id":57,"type":"PtnConvModel","pos":[2770.126708984375,1380.5203857421875],"size":[315,202],"flags":{},"order":7,"mode":0,"inputs":[],"outputs":[{"name":"PTMODEL","type":"PTMODEL","links":[72,73],"slot_index":0}],"properties":{"Node name for S&R":"PtnConvModel"},"widgets_values":["(1,28,28)",0,10,"[32,64,128,256,512]","[3,3,3,3,1]","[1,1,1,1,0]","[True,True,True,True,False]"]}],"links":[[66,47,0,50,1,"PTDATALOADER"],[67,48,0,50,3,"PTDATALOADER"],[68,11,0,50,2,"PTOPTIMIZER"],[70,19,0,51,0,"STRING"],[71,50,0,19,0,"PTMODEL"],[72,57,0,11,0,"PTMODEL"],[73,57,0,50,0,"PTMODEL"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7251918251473778,"offset":[-2209.359108864266,-1203.1203019096897]},"node_versions":{"data-analysis":"11335e88b00ed3b4a5129f92d3d134854b6b4a92"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_abs.py b/modules/pytorch_wrapper/pt_abs.py deleted file mode 100644 index 3453cee..0000000 --- a/modules/pytorch_wrapper/pt_abs.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtAbs: - """ - Computes the absolute value of each element in a PyTorch tensor. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the absolute value of a PyTorch tensor element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the absolute function. - """ - return (torch.abs(tens_a),) diff --git a/modules/pytorch_wrapper/pt_acos.py b/modules/pytorch_wrapper/pt_acos.py deleted file mode 100644 index 1d68c2a..0000000 --- a/modules/pytorch_wrapper/pt_acos.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtAcos: - """ - Computes the arccosine (inverse cosine) of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise arccosine (inverse cosine) of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. Values must be in the range [-1, 1]. - - Returns: - tuple: A tuple containing the resultant tensor after applying the arccosine function. - """ - return (torch.acos(tens_a),) diff --git a/modules/pytorch_wrapper/pt_add.py b/modules/pytorch_wrapper/pt_add.py deleted file mode 100644 index 4220656..0000000 --- a/modules/pytorch_wrapper/pt_add.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtAdd: - """ - Adds two PyTorch tensors. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Adds two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports addition with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.add(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_arange.py b/modules/pytorch_wrapper/pt_arange.py deleted file mode 100644 index 8d33fb1..0000000 --- a/modules/pytorch_wrapper/pt_arange.py +++ /dev/null @@ -1,62 +0,0 @@ -import os -import sys -from typing import Any, Dict, Tuple -import torch -from .utils import DTYPE_MAPPING - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from cda.utils import str_to_number, str_to_number_with_default - - -class PtArange: - """ - Creates a PyTorch tensor using `torch.arange` with the specified start, end, and step values. - - The values are parsed from string inputs and converted to numeric types. This allows users to specify - tensor range values in text fields. The function also ensures proper dtype selection. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "start": ("STRING", {"default":"", "multiline": False}), - "end": ("STRING", {"default":"", "multiline": False}), - "step": ("STRING", {"default":"", "multiline": False}), - "data_type": (("float32", "float16", "bfloat16", "float64", "uint8", "int8", "int16", "int32", "int64"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - - def f(self, start: str, end: str, step: str, data_type: str) -> Tuple[torch.Tensor]: - """ - Creates a PyTorch tensor using `torch.arange` with the given start, stop, and step values. - - Args: - start (str): The starting value of the sequence. If empty, defaults to 0. - end (str): The end value of the sequence (exclusive). - step (str): The step size for generating the sequence. If empty, defaults to 1. - data_type (str): The desired PyTorch dtype for the resulting tensor. - - Returns: - Tuple[torch.Tensor]: A tuple containing the generated PyTorch tensor. - """ - start_value = str_to_number_with_default(start, 0) - end_value = str_to_number(end) - step_value = str_to_number_with_default(step, 1) - tens = torch.arange(start_value, end_value, step_value, dtype=DTYPE_MAPPING[data_type]) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_argmax.py b/modules/pytorch_wrapper/pt_argmax.py deleted file mode 100644 index 1e78222..0000000 --- a/modules/pytorch_wrapper/pt_argmax.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtArgmax: - """ - Computes the indices of the maximum values of a PyTorch tensor along the specified dimension(s). - - Specify the dimension in the `dim` field using an integer as shown below: - ``` - 0 - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the indices of the maximum values along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute argmax, - e.g., "0" or "". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the tensor with indices of maximum values. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the argmax along the specified dimension(s) - tens = torch.argmax(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_argmin.py b/modules/pytorch_wrapper/pt_argmin.py deleted file mode 100644 index 0f4e30a..0000000 --- a/modules/pytorch_wrapper/pt_argmin.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtArgmin: - """ - Computes the indices of the minimum values of a PyTorch tensor along the specified dimension(s). - - Specify the dimension in the `dim` field using an integer as shown below: - ``` - 0 - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the indices of the minimum values along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute argmin, - e.g., "0" or "". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the tensor with indices of minimum values. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the argmin along the specified dimension(s) - tens = torch.argmin(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_asin.py b/modules/pytorch_wrapper/pt_asin.py deleted file mode 100644 index ef9b6dd..0000000 --- a/modules/pytorch_wrapper/pt_asin.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtAsin: - """ - Computes the arcsine (inverse sine) of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise arcsine (inverse sine) of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. Values must be in the range [-1, 1]. - - Returns: - tuple: A tuple containing the resultant tensor after applying the arcsine function. - """ - return (torch.asin(tens_a),) diff --git a/modules/pytorch_wrapper/pt_atan.py b/modules/pytorch_wrapper/pt_atan.py deleted file mode 100644 index 93e8c68..0000000 --- a/modules/pytorch_wrapper/pt_atan.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtAtan: - """ - Computes the arc tangent (inverse tangent) of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise arc tangent (inverse tangent) of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the arc tangent function. - """ - return (torch.atan(tens_a),) diff --git a/modules/pytorch_wrapper/pt_bitwise_and.py b/modules/pytorch_wrapper/pt_bitwise_and.py deleted file mode 100644 index ca130ef..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_and.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseAnd: - """ - Performs a bitwise AND operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a bitwise AND operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and integer type as `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise AND. - """ - return (torch.bitwise_and(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bitwise_left_shift.py b/modules/pytorch_wrapper/pt_bitwise_left_shift.py deleted file mode 100644 index 19cea42..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_left_shift.py +++ /dev/null @@ -1,42 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseLeftShift: - """ - Performs a bitwise left shift operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a bitwise left shift operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and integer type as `tens_a`, - representing the number of positions to shift. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise left shift. - """ - return (torch.bitwise_left_shift(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bitwise_not.py b/modules/pytorch_wrapper/pt_bitwise_not.py deleted file mode 100644 index 7fb05c0..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_not.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseNot: - """ - Performs a bitwise NOT operation on a PyTorch tensor element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Performs a bitwise NOT operation on a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise NOT. - """ - return (torch.bitwise_not(tens_a),) diff --git a/modules/pytorch_wrapper/pt_bitwise_or.py b/modules/pytorch_wrapper/pt_bitwise_or.py deleted file mode 100644 index b5d86f8..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_or.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseOr: - """ - Performs a bitwise OR operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a bitwise OR operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and integer type as `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise OR. - """ - return (torch.bitwise_or(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bitwise_right_shift.py b/modules/pytorch_wrapper/pt_bitwise_right_shift.py deleted file mode 100644 index fafde91..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_right_shift.py +++ /dev/null @@ -1,42 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseRightShift: - """ - Performs a bitwise right shift operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a bitwise right shift operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and integer type as `tens_a`, - representing the number of positions to shift. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise right shift. - """ - return (torch.bitwise_right_shift(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bitwise_xor.py b/modules/pytorch_wrapper/pt_bitwise_xor.py deleted file mode 100644 index bf910e0..0000000 --- a/modules/pytorch_wrapper/pt_bitwise_xor.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBitwiseXor: - """ - Performs a bitwise XOR operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Bitwise operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a bitwise XOR operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of integer type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and integer type as `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor after applying bitwise XOR. - """ - return (torch.bitwise_xor(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bmm.py b/modules/pytorch_wrapper/pt_bmm.py deleted file mode 100644 index 9bebbc6..0000000 --- a/modules/pytorch_wrapper/pt_bmm.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import Any, Dict -import torch - -class PtBmm: - """ - Performs batched matrix multiplication on two 3D PyTorch tensors. - - category: PyTorch wrapper - Matrix operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs batched matrix multiplication on two 3D PyTorch tensors. - - Args: - tens_a (torch.Tensor): A 3D PyTorch tensor (batch, m, n). - tens_b (torch.Tensor): A 3D PyTorch tensor (batch, n, p) that supports matrix multiplication with `tens_a`. - - Returns: - tuple: A tuple containing the resultant 3D tensor. - """ - if tens_a.dim() != 3 or tens_b.dim() != 3: - raise ValueError("torch.bmm() only supports batch matrix multiplication for 3D tensors.") - - return (torch.bmm(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_bool_create.py b/modules/pytorch_wrapper/pt_bool_create.py deleted file mode 100644 index 016e34a..0000000 --- a/modules/pytorch_wrapper/pt_bool_create.py +++ /dev/null @@ -1,51 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtBoolCreate: - """ - Creates a PyTorch tensor of dtype bool from True or False values entered as a list in the text field. - For example, entering: - ``` - [True, False, False] - ``` - will create a 1D boolean tensor. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "data": ("STRING", {"multiline": True}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, data: str) -> tuple: - """ - Creates a PyTorch tensor with bool data type using True or False string values entered in the text field. - - Args: - data (str): String value in the text field. - - Returns: - tuple: A tuple containing the tensor. - """ - # Convert string to Python list - list_data = ast.literal_eval(data) - - # Convert list to PyTorch tensor - tensor = torch.tensor(list_data, dtype=torch.bool) - return (tensor,) diff --git a/modules/pytorch_wrapper/pt_cos.py b/modules/pytorch_wrapper/pt_cos.py deleted file mode 100644 index 7a66956..0000000 --- a/modules/pytorch_wrapper/pt_cos.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtCos: - """ - Computes the cosine of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise cosine of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type, representing angles in radians. - - Returns: - tuple: A tuple containing the resultant tensor after applying the cosine function. - """ - return (torch.cos(tens_a),) diff --git a/modules/pytorch_wrapper/pt_cosh.py b/modules/pytorch_wrapper/pt_cosh.py deleted file mode 100644 index b168937..0000000 --- a/modules/pytorch_wrapper/pt_cosh.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtCosh: - """ - Computes the hyperbolic cosine of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise hyperbolic cosine of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the hyperbolic cosine function. - """ - return (torch.cosh(tens_a),) diff --git a/modules/pytorch_wrapper/pt_crop.py b/modules/pytorch_wrapper/pt_crop.py deleted file mode 100644 index 45c1fc3..0000000 --- a/modules/pytorch_wrapper/pt_crop.py +++ /dev/null @@ -1,65 +0,0 @@ -from typing import Any, Dict -import torch - -class PtCrop: - """ - Crops a PyTorch tensor to the specified size. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - - In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - - This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "height": ("INT", {"default":0, "min":1, "max": 16384}), - "width": ("INT", {"default":0, "min":1, "max": 16384}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, height: int, width: int) -> tuple: - """ - Crops a PyTorch tensor. - - Args: - tens (torch.Tensor): A PyTorch tensor with the shape of (c, h, w) or (b, c, h, w). - height (int): New image height. - width (int): New image width. - - Returns: - tuple: A tuple containing a transformed tensor`. - """ - dim = tens.dim() - if dim == 3: # c, h, w - image_height = tens.size(1) - image_width = tens.size(2) - elif dim == 4: # b, c, h, w - image_height = tens.size(2) - image_width = tens.size(3) - else: - raise ValueError("Only rank 3 or 4 tensors are supported for crop.") - - if height > image_height or width > image_width: - raise ValueError("Specified crop size exceeds tensor dimensions.") - - # Compute starting position for cropping - top = max(int((height - image_height) / 2), 0) - left = max(int((width - image_width) / 2), 0) - - tens2 = tens[..., top:top+height, left:left+width] - return (tens2,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_data_loader.py b/modules/pytorch_wrapper/pt_data_loader.py deleted file mode 100644 index 7ec163b..0000000 --- a/modules/pytorch_wrapper/pt_data_loader.py +++ /dev/null @@ -1,81 +0,0 @@ -import inspect -from typing import Any, Dict -import ast -import torch -from torch.utils.data import DataLoader - - -class PtDataLoader: - """ - Loads data from a dataset node and creates a PyTorch DataLoader. - - **dataset** - Connect a PtvDataset node that provides the dataset. - - **batch size** - Specifies the number of samples per batch. - - **shuffle** - If True, shuffles the dataset before each epoch. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types required for data loading. - - Returns: - Dict[str, Any]: A dictionary specifying required and optional input types. - """ - return { - "required": { - "dataset": ("PTVDATASET", {}), - "batch_size": ("INT", {"default": 1, "min": 1, "max": 1e6}), - "shuffle": ("BOOLEAN", {"default": False}), - }, - "optional": { - "parameters": ("STRING", {"default": "", "multiline": True}) - } - } - - RETURN_TYPES: tuple = ("PTDATALOADER",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, - dataset: Any, # One of the classes defined in torchvision.datasets - batch_size: int, - shuffle: bool, - parameters: str) -> tuple: - """ - Creates a PyTorch DataLoader for the given dataset. - - Args: - dataset (torchvision.datasets.{MNIST, ...}): An instance of a dataset from torchvision.datasets. - batch_size (int): The number of samples per batch. - shuffle (bool): If True, shuffles the dataset before each epoch. - parameters (str): Additional parameters in Python dictionary format. - - Returns: - tuple: A tuple containing the created DataLoader instance. - """ - with torch.inference_mode(False): - param_dict = ast.literal_eval(parameters) - - # Get valid parameters for the DataLoader class - valid_params = inspect.signature(DataLoader).parameters - - # Filter only parameters that match the dataset's constructor - filtered_params = {k: v for k, v in param_dict.items() if k in valid_params} - - dl = DataLoader(dataset=dataset, - batch_size=batch_size, - shuffle=shuffle, - **filtered_params) - return (dl,) diff --git a/modules/pytorch_wrapper/pt_div.py b/modules/pytorch_wrapper/pt_div.py deleted file mode 100644 index db87bc0..0000000 --- a/modules/pytorch_wrapper/pt_div.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtDiv: - """ - Divides one PyTorch tensor by another element-wise. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Divides one PyTorch tensor by another element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports element-wise division with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.div(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_einsum.py b/modules/pytorch_wrapper/pt_einsum.py deleted file mode 100644 index ddd4dc8..0000000 --- a/modules/pytorch_wrapper/pt_einsum.py +++ /dev/null @@ -1,67 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtEinsum: - """ - Performs Tensor operations specified in the Einstein summation equation. - - Specify Einstein summation notation in the first socket. - Specify two tensors in tens_a, tens_b. If you specify the third tensor, specify in tens_c. - Otherwise, leave the socket unconnected. - - Sublist format is not supported. - - category: PyTorch wrapper - Matrix operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "equation": ("STRING", {"default": ""}), - "tens_a": ("TENSOR", {}) - }, - "optional":{ - "tens_b": ("TENSOR", {}), - "tens_c": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, - equation: str, - tens_a: torch.Tensor, - tens_b: torch.Tensor = None, - tens_c: torch.Tensor = None) -> tuple: - """ - Performs Tensor operations specified in the Einstein summation equation. - - Args: - equation (str): Einstein summation equation. - tens_a (torch.Tensor): A PyTorch tensor. - tens_b (torch.Tensor): A PyTorch tensor. - tens_c (torch.Tensor): A PyTorch tensor. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - if tens_a is None: - raise ValueError("tens_a is None") - - if tens_b is None and tens_c is None: - tens_ret_val = torch.einsum(equation, tens_a) - elif tens_c is None: - tens_ret_val = torch.einsum(equation, tens_a, tens_b) - else: - tens_ret_val = torch.einsum(equation, tens_a, tens_b, tens_c) - return (tens_ret_val,) diff --git a/modules/pytorch_wrapper/pt_eq.py b/modules/pytorch_wrapper/pt_eq.py deleted file mode 100644 index ffadbce..0000000 --- a/modules/pytorch_wrapper/pt_eq.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtEq: - """ - Tests whether two PyTorch tensors are equal element-wise. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise equality. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating element-wise equality. - """ - return (torch.eq(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_evaluate_classification_model.py b/modules/pytorch_wrapper/pt_evaluate_classification_model.py deleted file mode 100644 index f915c32..0000000 --- a/modules/pytorch_wrapper/pt_evaluate_classification_model.py +++ /dev/null @@ -1,71 +0,0 @@ -from typing import Any, Dict, Tuple -import torch -import torch.nn as nn -import torch.nn.functional as F -from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score - -class PtEvaluateClassificationModel: - """ - Performs inference on test data and computes evaluation metrics. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "data_loader": ("PTDATALOADER", {}), - "use_gpu": ("BOOLEAN", {"default":False}) - } - } - - RETURN_NAMES: Tuple[str, ...] = ("accuracy", "precision", "recall", "f1", "num_samples") - RETURN_TYPES: Tuple[str, ...] = ("FLOAT", "FLOAT", "FLOAT", "FLOAT", "INT") - FUNCTION: str = "f" - CATEGORY: str = "Training" - - def f(self, model: nn.Module, data_loader: torch.utils.data.DataLoader, use_gpu: bool) -> Tuple[float, float, float, float, int]: - """ - Performs inference on test data and computes evaluation metrics. - - Args: - model (torch.nn.Module): The PyTorch model to evaluate. - data_loader (torch.utils.data.DataLoader): DataLoader for the test dataset. - use_gpu (bool): Whether to use GPU for inference. - - Returns: - Tuple[float, float, float, float, int]: A tuple containing accuracy, precision, recall, - F1-score, and the number of samples. - """ - - with torch.inference_mode(): - if use_gpu: - model.to("cuda") - model.train(False) # TODO: Change to model.*e*v*a*l() once Comfy's security checker is fixed. - y_hat = [] - y = [] - - for images, labels in data_loader: - if use_gpu: - images = images.to("cuda") - labels = labels.to("cuda") - outputs = model(images) - preds = outputs.argmax(dim=1) - - y_hat.extend(preds.cpu().numpy()) - y.extend(labels.cpu().numpy()) - - accuracy = accuracy_score(y, y_hat) - precision = precision_score(y, y_hat, average='macro') - recall = recall_score(y, y_hat, average='macro') - f1 = f1_score(y, y_hat, average='macro') - num_samples = len(y) - return (accuracy, precision, recall, f1, num_samples) diff --git a/modules/pytorch_wrapper/pt_exp.py b/modules/pytorch_wrapper/pt_exp.py deleted file mode 100644 index 3773009..0000000 --- a/modules/pytorch_wrapper/pt_exp.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtExp: - """ - Performs an exponential operation on a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise exponential of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the exponential function. - """ - return (torch.exp(tens_a),) diff --git a/modules/pytorch_wrapper/pt_flatten.py b/modules/pytorch_wrapper/pt_flatten.py deleted file mode 100644 index ac56d3a..0000000 --- a/modules/pytorch_wrapper/pt_flatten.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtFlatten: - """ - Flattens a PyTorch tensor into a 1D tensor. - - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Flattens a PyTorch tensor into a 1D tensor. - - Args: - tens (torch.Tensor): A PyTorch tensor of any shape. - - Returns: - tuple: A tuple containing the flattened tensor. - """ - return (tens.flatten(),) diff --git a/modules/pytorch_wrapper/pt_float_create.py b/modules/pytorch_wrapper/pt_float_create.py deleted file mode 100644 index 264b986..0000000 --- a/modules/pytorch_wrapper/pt_float_create.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtFloatCreate: - """ - Creates a PyTorch tensor with 32-bit floating point precision - using values entered in the text field. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "data": ("STRING", {"multiline": True}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, data: str) -> tuple: - """ - Creates a PyTorch tensor using values entered in the text field. - - Args: - data (str): String value in the text field. - - Returns: - tuple: A tuple containing the tensor. - """ - # Convert string to Python list - list_data = ast.literal_eval(data) - - # Convert list to PyTorch tensor - tensor = torch.tensor(list_data, dtype=torch.float32) - return (tensor,) diff --git a/modules/pytorch_wrapper/pt_floor_divide.py b/modules/pytorch_wrapper/pt_floor_divide.py deleted file mode 100644 index f579d98..0000000 --- a/modules/pytorch_wrapper/pt_floor_divide.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtFloorDiv: - """ - Performs element-wise floor division on two PyTorch tensors. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs element-wise floor division on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports element-wise floor division with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.floor_divide(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_from_image.py b/modules/pytorch_wrapper/pt_from_image.py deleted file mode 100644 index 8ee0d5e..0000000 --- a/modules/pytorch_wrapper/pt_from_image.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtFromImage: - """ - Casts an Image tensor as a PyTorch tensor. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "image": ("IMAGE", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, image: torch.Tensor) -> tuple: - """ - Casts an Image tensor as a PyTorch tensor. - - Args: - image (torch.Tensor): Image tensor - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - return (image,) diff --git a/modules/pytorch_wrapper/pt_from_image_transpose.py b/modules/pytorch_wrapper/pt_from_image_transpose.py deleted file mode 100644 index 4243728..0000000 --- a/modules/pytorch_wrapper/pt_from_image_transpose.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtFromImageTranspose: - """ - Casts an image tensor to a PyTorch tensor and transposes it from (H, W, C) to (C, H, W). For rank-4 inputs, the batch axis remains unchanged. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "image": ("IMAGE", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, image: torch.Tensor) -> tuple: - """ - Casts an Image tensor as a PyTorch tensor. - - Args: - image (torch.Tensor): Image tensor - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - if image.dim() == 3: - tens = image.permute(2, 0, 1) - elif image.dim() == 4: - tens = image.permute(0, 3, 1, 2) - else: - raise ValueError("Only rank 3 or 4 tensors are supported.") - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_from_latent.py b/modules/pytorch_wrapper/pt_from_latent.py deleted file mode 100644 index bfb581b..0000000 --- a/modules/pytorch_wrapper/pt_from_latent.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtFromLatent: - """ - Casts a latent tensor as a PyTorch tensor. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "latent": ("LATENT", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, latent: torch.Tensor) -> tuple: - """ - Casts a latent tensor as a PyTorch tensor. - - Args: - latent (torch.Tensor): Latent tensor - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - return (latent["samples"],) diff --git a/modules/pytorch_wrapper/pt_from_numpy.py b/modules/pytorch_wrapper/pt_from_numpy.py deleted file mode 100644 index 0c068d8..0000000 --- a/modules/pytorch_wrapper/pt_from_numpy.py +++ /dev/null @@ -1,42 +0,0 @@ -from typing import Any, Dict, Tuple -import numpy as np -import torch - - -class PtFromNumpy: - """ - Converts a NumPy ndarray to a PyTorch tensor while preserving its data type. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "array": ("NDARRAY", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, array: np.ndarray) -> Tuple[torch.Tensor]: - """ - Converts a NumPy ndarray to a PyTorch tensor while preserving its data type. - - Args: - array (np.ndarray): NumPy ndarray. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - tens = torch.tensor(array, dtype=torch.from_numpy(array).dtype) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_full.py b/modules/pytorch_wrapper/pt_full.py deleted file mode 100644 index 8ce80a8..0000000 --- a/modules/pytorch_wrapper/pt_full.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import DTYPE_MAPPING - -class PtFull: - """ - Creates a PyTorch tensor filled with a specified value using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32 filled with 7, enter: - [2,3,96,32] for size and 7 for value. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "value": ("STRING", {"multiline": False}), - "size": ("STRING", {"multiline": True}), - "data_type": (("float32", "float16", "bfloat16", "float64", "uint8", "int8", "int16", "int32", "int64", "bool"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, value: str, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor filled with a specified value. - - Args: - value (str): String representing the value to fill the tensor. - size (str): String representation of the tensor size. - data_type (str): Desired data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert the value to the appropriate type - dtype = DTYPE_MAPPING[data_type] - - if dtype in {torch.float32, torch.float16, torch.bfloat16, torch.float64}: - fill_value = float(value) - elif dtype in {torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64}: - fill_value = int(value) - elif dtype == torch.bool: - fill_value = value.lower() in {"true", "1"} - else: - raise ValueError(f"Unsupported data type: {data_type}") - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - tens = torch.full(sz, fill_value, dtype=dtype) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_gather.py b/modules/pytorch_wrapper/pt_gather.py deleted file mode 100644 index 82c301b..0000000 --- a/modules/pytorch_wrapper/pt_gather.py +++ /dev/null @@ -1,94 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtGather: - """ - Generates a tensor based on the index tensor using PyTorch's `gather` function. - - Specify the `dim` field using an integer to indicate the axis along which to gather elements. - Each input tensor element is selected based on the index tensor. - - For example, consider the following input tensor: - ``` - [ [10, 20, 30, 40, 50], - [100, 200, 300, 400, 500]] - ``` - - and the corresponding index tensor: - - ``` - [ [0, 4, 3, 2, 0], - [4, 3, 0, 0, 0]] - ``` - - If `dim = 0`, the function scans row-wise, treating each index value as a row index. - If `dim = 1`, it scans column-wise, interpreting each index value as a column index. - - Let's analyze the case where `dim = 1`: - - * Start at row 0, column 0. - * The index at this position is `index[0, 0] = 0`. - * PyTorch selects the value at position 0 from the array `[10, 20, 30, 40, 50]`, which is `10`. - * The result at this stage is: - ``` - [[10, ?, ?, ?, ?] - [?, ?, ?, ?, ?]] - ``` - - * Moving to column 1: `index[0, 1] = 4`. - * The value at index 4 in `[10, 20, 30, 40, 50]` is `50`. - * The updated result is: - ``` - [[10, 50, ?, ?, ?] - [?, ?, ?, ?, ?]] - ``` - - * Repeating this process for all elements constructs the final gathered tensor. - - category: PyTorch wrapper - Indexing and Slicing Operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("INT", {"default": 0, "min": -10, "max": 10}), - "index": ("STRING", {"multiline": True}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: int, index: str) -> tuple: - """ - Gathers elements along the specified dimension using an index tensor. - - Args: - tens (torch.Tensor): The input tensor. - dim (int): The dimension along which to gather values. - index (str): A string representation of the index tensor, provided in list format. - - Returns: - tuple: A tuple containing the gathered tensor. - """ - # Parse the index string to a Python list - index = ast.literal_eval(index) - - # Convert the parsed list to a tensor - index_tensor = torch.tensor(index, dtype=torch.long, device=tens.device) - - # Perform the gather operation - gathered_tens = torch.gather(tens, dim=dim, index=index_tensor) - - return (gathered_tens,) diff --git a/modules/pytorch_wrapper/pt_ge.py b/modules/pytorch_wrapper/pt_ge.py deleted file mode 100644 index 9fc7798..0000000 --- a/modules/pytorch_wrapper/pt_ge.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtGe: - """ - Tests whether elements in the first PyTorch tensor are greater than or equal to the corresponding elements in the second tensor. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise greater-than-or-equal-to condition. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating where `tens_a >= tens_b`. - """ - return (torch.ge(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_gt.py b/modules/pytorch_wrapper/pt_gt.py deleted file mode 100644 index f30d6f5..0000000 --- a/modules/pytorch_wrapper/pt_gt.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtGt: - """ - Tests whether elements in the first PyTorch tensor are greater than the corresponding elements in the second tensor. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise greater-than condition. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating where `tens_a > tens_b`. - """ - return (torch.gt(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_index_select.py b/modules/pytorch_wrapper/pt_index_select.py deleted file mode 100644 index 8903e68..0000000 --- a/modules/pytorch_wrapper/pt_index_select.py +++ /dev/null @@ -1,78 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtIndexSelect: - """ - Extracts elements from the input tensor along a specified dimension using an index tensor. - - `dim` specifies the dimension along which the selection occurs. - * For example, for 2D tensors: - ** If `dim=0`, `index` selects rows. - ** If `dim=1`, `index` selects columns (for 2D tensors). - - `index` is a list of indices that will be converted into a tensor. - - Example: - ``` - Input Tensor: - [[1, 2, 3], - [40, 50, 60], - [700, 800, 900]] - - index = "[0, 2]" - dim = 0 - - Output Tensor: - [[1, 2, 3], - [700, 800, 900]] - ``` - - category: PyTorch wrapper - Indexing and Slicing Operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("INT", {"default": 0, "min": -10, "max": 10}), - "index": ("STRING", {"multiline": True}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: int, index: str) -> tuple: - """ - Extracts elements from the input tensor along the specified dimension. - - Args: - tens (torch.Tensor): The input tensor. - dim (int): The dimension along which elements are selected. - index (str): A string representation of a list of indices, e.g., "[0, 2]". - - Returns: - tuple: A tuple containing the selected tensor. - """ - # Convert the string index to a Python list - index_list = ast.literal_eval(index) - if not isinstance(index_list, list): - raise ValueError("Index must be a list of integers.") - - # Convert the index list to a tensor - index_tensor = torch.tensor(index_list, dtype=torch.long) - - # Perform index selection - result = torch.index_select(tens, dim=dim, index=index_tensor) - - return (result,) diff --git a/modules/pytorch_wrapper/pt_int_create.py b/modules/pytorch_wrapper/pt_int_create.py deleted file mode 100644 index a1bdb9e..0000000 --- a/modules/pytorch_wrapper/pt_int_create.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtIntCreate: - """ - Creates a PyTorch tensor with 32-bit integer - using values entered in the text field. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "data": ("STRING", {"multiline": True}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, data: str) -> tuple: - """ - Creates a PyTorch tensor using values entered in the text field. - - Args: - data (str): String value in the text field. - - Returns: - tuple: A tuple containing the tensor. - """ - # Convert string to Python list - list_data = ast.literal_eval(data) - - # Convert list to PyTorch tensor - tensor = torch.tensor(list_data, dtype=torch.int32) - return (tensor,) diff --git a/modules/pytorch_wrapper/pt_interpolate_by_scale_factor.py b/modules/pytorch_wrapper/pt_interpolate_by_scale_factor.py deleted file mode 100644 index f1a5dc7..0000000 --- a/modules/pytorch_wrapper/pt_interpolate_by_scale_factor.py +++ /dev/null @@ -1,56 +0,0 @@ -from typing import Any, Dict -import torch - -class PtInterpolateByScaleFactor: - """ - Resizes a PyTorch tensor using interpolation by scale factor. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - - In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - - This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "scale_factor": ("FLOAT", {"default":2.0, "min":0.01, "max": 100.0, "step":0.01}), - "mode": (("nearest-exact", "bilinear", "bicubic", "nearest"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, scale_factor: float, mode: str) -> tuple: - """ - Resizes a PyTorch tensor using interpolation. - - Args: - tens (torch.Tensor): A PyTorch tensor with the shape of (c, h, w) or (b, c, h, w). - scale_factor (float): Scale factor. - mode (string): Interpolation mode. - - Returns: - tuple: A tuple containing a transformed tensor`. - """ - if tens.dim() == 3: - rank3 = True - tens_adjusted = torch.unsqueeze(tens, 0) - else: - rank3 = False - tens_adjusted = tens - tens2 = torch.nn.functional.interpolate(tens_adjusted, scale_factor=scale_factor, mode=mode) - if rank3: - tens2 = torch.squeeze(tens2, 0) - return (tens2,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_interpolate_to_size.py b/modules/pytorch_wrapper/pt_interpolate_to_size.py deleted file mode 100644 index b2183da..0000000 --- a/modules/pytorch_wrapper/pt_interpolate_to_size.py +++ /dev/null @@ -1,60 +0,0 @@ -from typing import Any, Dict -import torch - -class PtInterpolateToSize: - """ - Resizes a PyTorch tensor using interpolation. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - - In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - - This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "height": ("INT", {"default":0, "min":1, "max": 16384}), - "width": ("INT", {"default":0, "min":1, "max": 16384}), - "mode": (("nearest-exact", "bilinear", "bicubic", "nearest"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, height: int, width: int, mode: str) -> tuple: - """ - Resizes a PyTorch tensor using interpolation. - - Args: - tens (torch.Tensor): A PyTorch tensor with the shape of (c, h, w) or (b, c, h, w). - height (int): New image height. - width (int): New image width. - mode (string): Interpolation mode. - - Returns: - tuple: A tuple containing a transformed tensor`. - """ - if tens.dim() == 3: - rank3 = True - tens_adjusted = torch.unsqueeze(tens, 0) - else: - rank3 = False - tens_adjusted = tens - - tens2 = torch.nn.functional.interpolate(tens_adjusted, size=(height, width), mode=mode) - - if rank3: - tens2 = torch.squeeze(tens2, 0) - return (tens2,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_le.py b/modules/pytorch_wrapper/pt_le.py deleted file mode 100644 index 641cf79..0000000 --- a/modules/pytorch_wrapper/pt_le.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLe: - """ - Tests whether elements in the first PyTorch tensor are less than or equal to the corresponding elements in the second tensor. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise less-than-or-equal-to condition. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating where `tens_a <= tens_b`. - """ - return (torch.le(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_linspace.py b/modules/pytorch_wrapper/pt_linspace.py deleted file mode 100644 index 731b1bc..0000000 --- a/modules/pytorch_wrapper/pt_linspace.py +++ /dev/null @@ -1,62 +0,0 @@ -import os -import sys -from typing import Any, Dict, Tuple -import torch -from .utils import DTYPE_MAPPING - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from cda.utils import str_to_number, str_to_number_with_default - - -class PtLinspace: - """ - Creates a PyTorch tensor using `torch.linspace` with the specified start, end, and steps values. - - The start and end values are parsed from string inputs and converted to a float. - The steps value is converted to an int. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "start": ("STRING", {"default":"", "multiline": False}), - "end": ("STRING", {"default":"", "multiline": False}), - "steps": ("STRING", {"default":"", "multiline": False}), - "data_type": (("float32", "float16", "bfloat16", "float64", "uint8", "int8", "int16", "int32", "int64"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - - def f(self, start: str, end: str, steps: str, data_type: str) -> Tuple[torch.Tensor]: - """ - Creates a PyTorch tensor using `torch.arange` with the given start, end, and step values. - - Args: - start (str): The starting value of the sequence. - end (str): The end value of the sequence (inclusive). - steps (str): The number of steps - data_type (str): The desired PyTorch dtype for the resulting tensor. - - Returns: - Tuple[torch.Tensor]: A tuple containing the generated PyTorch tensor. - """ - start_value = float(start) - end_value = float(end) - steps_value = int(steps) - tens = torch.linspace(start_value, end_value, steps_value, dtype=DTYPE_MAPPING[data_type]) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_load_model.py b/modules/pytorch_wrapper/pt_load_model.py deleted file mode 100644 index eb65601..0000000 --- a/modules/pytorch_wrapper/pt_load_model.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -from typing import Any, Dict -import torch -from .utils import get_model_full_path - -class PtLoadModel: - """ - A wrapper class for saving a PyTorch model. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "model_path": ("STRING", {"default": "model.pkl"}) - } - } - - RETURN_NAMES: tuple = ("model",) - RETURN_TYPES: tuple = ("PTMODEL",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, model:Any, model_path: str): - model_full_path = get_model_full_path(model_path) - sd = torch.load(model_full_path, weights_only=True) - model.load_state_dict(sd) - return (model,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_log.py b/modules/pytorch_wrapper/pt_log.py deleted file mode 100644 index bebd1d7..0000000 --- a/modules/pytorch_wrapper/pt_log.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLog: - """ - Computes the natural logarithm (log base e) of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise natural logarithm (log base e) of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. Must contain only positive values. - - Returns: - tuple: A tuple containing the resultant tensor after applying the natural logarithm. - """ - return (torch.log(tens_a),) diff --git a/modules/pytorch_wrapper/pt_logical_and.py b/modules/pytorch_wrapper/pt_logical_and.py deleted file mode 100644 index 0b19d48..0000000 --- a/modules/pytorch_wrapper/pt_logical_and.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLogicalAnd: - """ - Performs a logical AND operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Logical operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a logical AND operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of boolean or numerical type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and type as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor where `tens_a AND tens_b` is applied element-wise. - """ - return (torch.logical_and(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_logical_not.py b/modules/pytorch_wrapper/pt_logical_not.py deleted file mode 100644 index 60c83dd..0000000 --- a/modules/pytorch_wrapper/pt_logical_not.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLogicalNot: - """ - Performs a logical NOT operation on a PyTorch tensor element-wise. - - category: PyTorch wrapper - Logical operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Performs a logical NOT operation on a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of boolean or numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying logical NOT. - """ - return (torch.logical_not(tens_a),) diff --git a/modules/pytorch_wrapper/pt_logical_or.py b/modules/pytorch_wrapper/pt_logical_or.py deleted file mode 100644 index 8a6d1f7..0000000 --- a/modules/pytorch_wrapper/pt_logical_or.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLogicalOr: - """ - Performs a logical OR operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Logical operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a logical OR operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of boolean or numerical type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and type as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor where `tens_a OR tens_b` is applied element-wise. - """ - return (torch.logical_or(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_logical_xor.py b/modules/pytorch_wrapper/pt_logical_xor.py deleted file mode 100644 index 4b162cb..0000000 --- a/modules/pytorch_wrapper/pt_logical_xor.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLogicalXor: - """ - Performs a logical XOR operation on two PyTorch tensors element-wise. - - category: PyTorch wrapper - Logical operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs a logical XOR operation on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of boolean or numerical type. - tens_b (torch.Tensor): A PyTorch tensor of the same shape and type as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor where `tens_a XOR tens_b` is applied element-wise. - """ - return (torch.logical_xor(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_lt.py b/modules/pytorch_wrapper/pt_lt.py deleted file mode 100644 index 2fafb48..0000000 --- a/modules/pytorch_wrapper/pt_lt.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtLt: - """ - Tests whether elements in the first PyTorch tensor are less than the corresponding elements in the second tensor. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise less-than condition. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating where `tens_a < tens_b`. - """ - return (torch.lt(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_masked_select.py b/modules/pytorch_wrapper/pt_masked_select.py deleted file mode 100644 index 3c825e7..0000000 --- a/modules/pytorch_wrapper/pt_masked_select.py +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtMaskedSelect: - """ - Extracts elements from the input tensor whose corresponding value in `masked_tens` is `True`. - - Example: - ``` - Input Tensor: - [[1, 2, 3], - [40, 50, 60], - [700, 800, 900]] - - Masked Tensor: - [[True, False, False], - [False, True, False], - [False, False, True]] - - Output Tensor: - [1, 50, 900] - ``` - - category: PyTorch wrapper - Indexing and Slicing Operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "masked_tens": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, masked_tens: torch.Tensor) -> tuple: - """ - Extracts elements from `tens` where `masked_tens` is `True`. - - Args: - tens (torch.Tensor): The input tensor. - masked_tens (torch.Tensor): A boolean tensor specifying which elements to select. - - Returns: - tuple: A tuple containing the selected tensor. - """ - if masked_tens.dtype != torch.bool: - raise ValueError("masked_tens must be a boolean tensor (dtype=torch.bool)") - - result = torch.masked_select(tens, masked_tens) - return (result,) diff --git a/modules/pytorch_wrapper/pt_matmul.py b/modules/pytorch_wrapper/pt_matmul.py deleted file mode 100644 index 6401bfe..0000000 --- a/modules/pytorch_wrapper/pt_matmul.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtMatMul: - """ - Performs matrix multiplication on two PyTorch tensors. - - category: PyTorch wrapper - Matrix operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs matrix multiplication on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of shape compatible for matrix multiplication. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports matrix multiplication with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.matmul(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_max.py b/modules/pytorch_wrapper/pt_max.py deleted file mode 100644 index ce3ec28..0000000 --- a/modules/pytorch_wrapper/pt_max.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import str_to_dim - -class PtMax: - """ - Computes the maximum values of a PyTorch tensor along the specified dimension(s). - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the maximum values along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the maximum, - e.g., "0", "[0]", or "(1, 2)". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the tensor with maximum values. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the max along the specified dimension(s) - tens = torch.amax(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_mean.py b/modules/pytorch_wrapper/pt_mean.py deleted file mode 100644 index 1745853..0000000 --- a/modules/pytorch_wrapper/pt_mean.py +++ /dev/null @@ -1,61 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtMean: - """ - Computes the mean of a PyTorch tensor along the specified dimension(s). - - This node supports only floating-point or complex tensors as input. - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the mean along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the mean, - e.g., "0", "[0]", or "(1, 2)". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the mean tensor. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the mean along the specified dimension(s) - tens = torch.mean(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_median.py b/modules/pytorch_wrapper/pt_median.py deleted file mode 100644 index 14971e5..0000000 --- a/modules/pytorch_wrapper/pt_median.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtMedian: - """ - Computes the median of a PyTorch tensor along the specified dimension(s). - - Specify the dimension(s) in the `dim` field using an integer as shown below: - ``` - 0 - ``` - or - ``` - 1 - ``` - Note that PtMedian calls torch.median(), which returns the lower of the two numbers when the true median falls between them. - - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the median along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the median, - e.g., "0", or "1". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the median tensor. - """ - dim = str_to_dim(dim) - if not isinstance(dim, int): - raise TypeError(f"Invalid type for dim: {dim}. Must be a integer.") - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the median along the specified dimension(s) - tens, _ = torch.median(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_min.py b/modules/pytorch_wrapper/pt_min.py deleted file mode 100644 index 87b3dd5..0000000 --- a/modules/pytorch_wrapper/pt_min.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtMin: - """ - Computes the minimum values of a PyTorch tensor along the specified dimension(s). - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the minimum values along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the minimum, - e.g., "0", "[0]", or "(1, 2)". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the tensor with minimum values. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the min along the specified dimension(s) - tens = torch.amin(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_mm.py b/modules/pytorch_wrapper/pt_mm.py deleted file mode 100644 index 16f33b1..0000000 --- a/modules/pytorch_wrapper/pt_mm.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import Any, Dict -import torch - -class PtMm: - """ - Performs 2D matrix multiplication on two PyTorch tensors. - - category: PyTorch wrapper - Matrix operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Performs 2D matrix multiplication on two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A 2D PyTorch tensor. - tens_b (torch.Tensor): A 2D PyTorch tensor that supports matrix multiplication with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - if tens_a.dim() != 2 or tens_b.dim() != 2: - raise ValueError("torch.mm() only supports 2D tensors.") - - return (torch.mm(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_mul.py b/modules/pytorch_wrapper/pt_mul.py deleted file mode 100644 index 1a4a1c1..0000000 --- a/modules/pytorch_wrapper/pt_mul.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtMul: - """ - Multiplies two PyTorch tensors element-wise. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Multiplies two PyTorch tensors element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports element-wise multiplication with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.mul(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_ne.py b/modules/pytorch_wrapper/pt_ne.py deleted file mode 100644 index cd8aab9..0000000 --- a/modules/pytorch_wrapper/pt_ne.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtNe: - """ - Tests whether two PyTorch tensors are not equal element-wise. - - category: PyTorch wrapper - Comparison operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Compares two PyTorch tensors for element-wise inequality. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of the same shape as `tens_a`. - - Returns: - tuple: A tuple containing a boolean tensor indicating element-wise inequality. - """ - return (torch.ne(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_neg.py b/modules/pytorch_wrapper/pt_neg.py deleted file mode 100644 index c0dd79c..0000000 --- a/modules/pytorch_wrapper/pt_neg.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtNeg: - """ - Computes the negation of each element in a PyTorch tensor. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the negation of a PyTorch tensor element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying negation. - """ - return (torch.neg(tens_a),) diff --git a/modules/pytorch_wrapper/pt_ones.py b/modules/pytorch_wrapper/pt_ones.py deleted file mode 100644 index 7d6131e..0000000 --- a/modules/pytorch_wrapper/pt_ones.py +++ /dev/null @@ -1,53 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import DTYPE_MAPPING - -class PtOnes: - """ - Creates a PyTorch tensor of ones using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: - [2,3,96,32] - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "size": ("STRING", {"multiline": True}), - "data_type": (("float32", "float16", "bfloat16", "float64", "uint8", "int8", "int16", "int32", "int64", "bool"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor of ones using the size entered in the text field. - - Args: - size (str): String value in the text field. - data_type (str): Desired data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - - tens = torch.ones(sz, dtype=DTYPE_MAPPING[data_type]) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_pad.py b/modules/pytorch_wrapper/pt_pad.py deleted file mode 100644 index 5300460..0000000 --- a/modules/pytorch_wrapper/pt_pad.py +++ /dev/null @@ -1,72 +0,0 @@ -from typing import Any, Dict -import torch - -class PtPad: - """ - Pads a PyTorch tensor to the specified size. Padded area will be black. The input tensor must have a shape of (c, h, w) or (b, c, h, w). - - In ComfyUI Analysis, the tensor data type is "TENSOR," while in ComfyUI, the type "IMAGE" is used. To pass image data from ComfyUI to a ComfyUI Analysis node (e.g., this interpolation node), first use the "Pt From Image" node to convert it to a tensor, then transpose the axes from (b, h, w, c) to (b, c, h, w) before passing it to this node. - - This transposition can be performed using the "Pt Permute" node with (0, 2, 3, 1). To convert the output back to an image, apply "Pt Permute" with (0, 3, 1, 2) and then use the "Pt To Image" node. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "height": ("INT", {"default":0, "min":1, "max": 16384}), - "width": ("INT", {"default":0, "min":1, "max": 16384}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, height: int, width: int) -> tuple: - """ - Pads a PyTorch tensor. - - Args: - tens (torch.Tensor): A PyTorch tensor with the shape of (c, h, w) or (b, c, h, w). - height (int): New image height. - width (int): New image width. - - Returns: - tuple: A tuple containing a transformed tensor. - """ - dim = tens.dim() - if dim == 3: # c, h, w - image_height = tens.size(1) - image_width = tens.size(2) - elif dim == 4: # b, c, h, w - image_height = tens.size(2) - image_width = tens.size(3) - else: - raise ValueError("Only rank 3 or 4 tensors are supported for padding.") - - if height < image_height or width < image_width: - raise ValueError("Specified dimensions must be greater than or equal to tensor dimensions.") - - # Compute starting position for padding - top = max((height - image_height) // 2, 0) - left = max((width - image_width) // 2, 0) - - if dim == 3: - tens2 = torch.zeros(tens.size(0), height, width, - dtype=tens.dtype, device=tens.device) - else: - tens2 = torch.zeros(tens.size(0), tens.size(1), height, width, - dtype=tens.dtype, device=tens.device) - - tens2[..., top:top+image_height, left:left+image_width] = tens - return (tens2,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_permute.py b/modules/pytorch_wrapper/pt_permute.py deleted file mode 100644 index 86ea0f8..0000000 --- a/modules/pytorch_wrapper/pt_permute.py +++ /dev/null @@ -1,60 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtPermute: - """ - Permutes the dimensions of a PyTorch tensor according to the specified order. - For example, if a tensor has shape (2, 3, 96, 32) and `new_axes="[0, 3, 1, 2]"`, - the output will have shape (2, 32, 3, 96). - - Specify the new axis order in the `new_axes` field using brackets, as shown below: - ``` - [0, 3, 1, 2] - ``` - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "new_axes": ("STRING", {"multiline": True}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, new_axes: str) -> tuple: - """ - Permutes the dimensions of the input tensor based on the specified order. - - Args: - tens (torch.Tensor): The input tensor. - new_axes (str): A string representation of the desired dimension order, - e.g., "[0, 3, 1, 2]" or "(0, 3, 1, 2)". - - Returns: - tuple: A tuple containing the permuted PyTorch tensor. - """ - # Convert string to a tuple of integers - permute_order = tuple(ast.literal_eval(new_axes)) - - # Ensure the parsed order is valid - if not isinstance(permute_order, tuple) or not all(isinstance(i, int) for i in permute_order): - raise ValueError(f"Invalid format for new_axes: {new_axes}. Must be a tuple or list of integers.") - - # Apply permutation - tens = tens.permute(*permute_order) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_pow.py b/modules/pytorch_wrapper/pt_pow.py deleted file mode 100644 index 52f3cb6..0000000 --- a/modules/pytorch_wrapper/pt_pow.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtPow: - """ - Raises one PyTorch tensor to the power of another element-wise. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Raises one PyTorch tensor to the power of another element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports element-wise exponentiation with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.pow(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_predict_classification_model.py b/modules/pytorch_wrapper/pt_predict_classification_model.py deleted file mode 100644 index e9e1e70..0000000 --- a/modules/pytorch_wrapper/pt_predict_classification_model.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import Any, Dict, Tuple -import torch -import torch.nn as nn -import torch.nn.functional as F -from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score - -class PtPredictClassificationModel: - """ - Performs inference on input data. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "inputs": ("TENSOR", {}), - "class_id_to_name_map": ("PYDICT", {}), - "use_gpu": ("BOOLEAN", {"default":False}) - } - } - - RETURN_NAMES: Tuple[str, ...] = ("class_name", "class_id", "probability") - RETURN_TYPES: Tuple[str, ...] = ("STRING", "INT", "FLOAT") - FUNCTION: str = "f" - CATEGORY: str = "Training" - - def f(self, model: nn.Module, - inputs: torch.Tensor, - class_id_to_name_map: Dict, - use_gpu: bool) -> Tuple[str, int, float]: - """ - Performs inference on test data and computes evaluation metrics. - - Args: - model (torch.nn.Module): The PyTorch model to evaluate. - inputs (torch.Tensor): Input image to predict the class for. - class_id_to_name_map (Dict): A Python dictionary contains the mapping of - class ID to class name. - use_gpu (bool): Whether to use GPU for inference. - - Returns: - Tuple[str, int, float]: A tuple containing "class_name", "class_id", "probability". - """ - - with torch.inference_mode(): - if use_gpu: - model.to("cuda") - model.train(False) # TODO: Change to model.*e*v*a*l() once Comfy's security checker is fixed. - x = torch.unsqueeze(inputs, 0) - if use_gpu: - x = x.to("cuda") - outputs = model(x) - class_id = outputs.argmax(dim=1)[0].detach().cpu().item() - prob = F.softmax(outputs, dim=1)[0][class_id].detach().cpu().item() - class_name = class_id_to_name_map[class_id] - - return (class_name, class_id, prob) diff --git a/modules/pytorch_wrapper/pt_prod.py b/modules/pytorch_wrapper/pt_prod.py deleted file mode 100644 index c40316a..0000000 --- a/modules/pytorch_wrapper/pt_prod.py +++ /dev/null @@ -1,65 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtProd: - """ - Computes the product of a PyTorch tensor along the specified dimension(s). - - Specify the dimension(s) in the `dim` field using an integer as shown below: - ``` - 0 - ``` - or - ``` - 1 - ``` - - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the product along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the product, - e.g., "0" or "1". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the product tensor. - """ - dim = str_to_dim(dim) - if not isinstance(dim, int): - raise TypeError(f"Invalid type for dim: {dim}. Must be a integer.") - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the product along the specified dimension(s) - tens = torch.prod(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_rand.py b/modules/pytorch_wrapper/pt_rand.py deleted file mode 100644 index 3d967ea..0000000 --- a/modules/pytorch_wrapper/pt_rand.py +++ /dev/null @@ -1,57 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import DTYPE_MAPPING - -class PtRand: - """ - Creates a PyTorch tensor with values sampled from a uniform distribution - using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: - [2,3,96,32] - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "size": ("STRING", {"multiline": True}), - "data_type": (("float32", "float16", "bfloat16", "float64"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor with values sampled from a uniform distribution. - - Args: - size (str): String value in the text field. - data_type (str): Desired floating-point data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - tens = torch.rand(sz, dtype=DTYPE_MAPPING[data_type]) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_rand_int.py b/modules/pytorch_wrapper/pt_rand_int.py deleted file mode 100644 index 071ea48..0000000 --- a/modules/pytorch_wrapper/pt_rand_int.py +++ /dev/null @@ -1,72 +0,0 @@ -import time -from typing import Any, Dict -import torch -import ast -import copy -from .utils import DTYPE_MAPPING - -class PtRandInt: - """ - Creates a PyTorch tensor filled with random integers within a specified range using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32 with random integers in the range [0, 10), - enter [2,3,96,32] for size, 0 for min_value, and 10 for max_value. - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "min_value": ("INT", {"default": 0, "min": -2**31, "max": 2**31}), - "max_value": ("INT", {"default": 1, "min": -2**31, "max": 2**31}), - "size": ("STRING", {"multiline": True}), - "data_type": (("uint8", "int8", "int16", "int32", "int64"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def __init__(self): - # Initialize a separate generator with a different seed - self.gen = torch.Generator() - self.gen.manual_seed(int(time.time() * 1000000) % (2**32)) # Unique seed - - def f(self, min_value: int, max_value: int, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor filled with random integers in the range [min_value, max_value). - - Args: - min_value (int): Minimum value (inclusive). - max_value (int): Maximum value (exclusive). - size (str): String representation of the tensor size. - data_type (str): Desired integer data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - - # Ensure max_value is greater than min_value - if max_value <= min_value: - raise ValueError("max_value must be greater than min_value.") - - # Generate random integers within the specified range - tens = torch.randint(min_value, max_value, sz, dtype=DTYPE_MAPPING[data_type], generator=self.gen) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_randn.py b/modules/pytorch_wrapper/pt_randn.py deleted file mode 100644 index 9084769..0000000 --- a/modules/pytorch_wrapper/pt_randn.py +++ /dev/null @@ -1,57 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import DTYPE_MAPPING - -class PtRandn: - """ - Creates a PyTorch tensor with values sampled from a standard normal distribution (mean=0, std=1) - using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: - [2,3,96,32] - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "size": ("STRING", {"multiline": True}), - "data_type": (("float32", "float16", "bfloat16", "float64"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor with values sampled from a standard normal distribution. - - Args: - size (str): String value in the text field. - data_type (str): Desired floating-point data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - tens = torch.randn(sz, dtype=DTYPE_MAPPING[data_type]) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_remainder.py b/modules/pytorch_wrapper/pt_remainder.py deleted file mode 100644 index 25c9591..0000000 --- a/modules/pytorch_wrapper/pt_remainder.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtRemainder: - """ - Computes the element-wise remainder of division between two PyTorch tensors. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Computes the element-wise remainder of division between two PyTorch tensors. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports element-wise remainder computation with `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.remainder(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_reshape.py b/modules/pytorch_wrapper/pt_reshape.py deleted file mode 100644 index a132f5d..0000000 --- a/modules/pytorch_wrapper/pt_reshape.py +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtReshape: - """ - Reshapes a PyTorch tensor into a specified shape using `torch.reshape()`. - The total number of elements must remain unchanged. - - For example, if a tensor has shape (2, 3, 4), and `new_shape="[6, 4]"`, - the output will have shape (6, 4). - - Use -1 to automatically infer a dimension, e.g.: - ``` - [2, -1] - ``` - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "new_shape": ("STRING", {"multiline": True}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, new_shape: str) -> tuple: - """ - Reshapes the input tensor based on the specified shape. - - Args: - tens (torch.Tensor): The input tensor. - new_shape (str): A string representation of the desired shape, - e.g., "[2, -1]" or "(6, 4)". - - Returns: - tuple: A tuple containing the reshaped PyTorch tensor. - """ - # Convert string to a tuple of integers - shape_order = tuple(ast.literal_eval(new_shape)) - - # Ensure the parsed shape is valid - if not isinstance(shape_order, tuple) or not all(isinstance(i, int) for i in shape_order): - raise ValueError(f"Invalid format for new_shape: {new_shape}. Must be a tuple or list of integers.") - - # Apply reshape operation - tens = tens.reshape(*shape_order) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_save_model.py b/modules/pytorch_wrapper/pt_save_model.py deleted file mode 100644 index 993c221..0000000 --- a/modules/pytorch_wrapper/pt_save_model.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -from typing import Any, Dict -import torch -from .utils import get_model_full_path - -class PtSaveModel: - """ - A wrapper class for saving a PyTorch model. - - category: IO - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "model_path": ("STRING", {"default": "model.pkl"}) - } - } - - RETURN_NAMES: tuple = ("model full path",) - RETURN_TYPES: tuple = ("STRING",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, model:Any, model_path: str): - model_full_path = get_model_full_path(model_path) - torch.save(model.state_dict(), model_full_path) - return (os.path.realpath(model_full_path),) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_scatter.py b/modules/pytorch_wrapper/pt_scatter.py deleted file mode 100644 index a629089..0000000 --- a/modules/pytorch_wrapper/pt_scatter.py +++ /dev/null @@ -1,69 +0,0 @@ -from typing import Any, Dict -import torch -import ast - -class PtScatter: - """ - Generates a new tensor by replacing values at specified positions using an index tensor. - - * Target tensor (tens): Some of whose values are replaced. - * Source tensor (src): Values from this tensor replace a part or whole of the target tensor. - * Index tensor (index): Specifies the positions in the target tensor for replacement. - - category: PyTorch wrapper - Indexing and Slicing Operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("INT", {"default": 0, "min": -10, "max": 10}), - "index": ("STRING", {"multiline": True}), - "src": ("STRING", {"multiline": True}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, - tens: torch.Tensor, - dim: int, - index: str, - src: str) -> tuple: - """ - Replaces elements in the target tensor along the specified dimension using an index tensor. - - Args: - tens (torch.Tensor): The target tensor whose values will be replaced. - dim (int): The dimension along which values are replaced. - index (str): A string representation of the index tensor (list format). - src (str): A string representation of the source tensor (list format). - - Returns: - tuple: A tuple containing the modified tensor. - """ - # Parse the input index and source tensors from string representations - index_list = ast.literal_eval(index) - src_list = ast.literal_eval(src) - - # Convert to tensors - index_tensor = torch.tensor(index_list, dtype=torch.long, device=tens.device) - src_tensor = torch.tensor(src_list, dtype=tens.dtype, device=tens.device) - - # Ensure index and src shapes match - if index_tensor.shape != src_tensor.shape: - raise ValueError(f"Shape mismatch: index tensor {index_tensor.shape} and src tensor {src_tensor.shape} must match.") - - # Perform the scatter operation - updated_tens = torch.scatter(tens.clone(), dim=dim, index=index_tensor, src=src_tensor) - - return (updated_tens,) diff --git a/modules/pytorch_wrapper/pt_show_size.py b/modules/pytorch_wrapper/pt_show_size.py deleted file mode 100644 index d8b154a..0000000 --- a/modules/pytorch_wrapper/pt_show_size.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Almost all of this code was taken from -https://github.com/pythongosssss/ComfyUI-Custom-Scripts/blob/main/py/show_text.py - -See credit/credit.md for the full license. -""" -from typing import List -import torch - - -class PtShowSize: - """ - Displays PyTorch Size object as a string. - - category: Display data - """ - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "size": ("PTSIZE", {}), - }, - "hidden": { - "unique_id": "UNIQUE_ID", - "extra_pnginfo": "EXTRA_PNGINFO", - }, - } - - INPUT_IS_LIST = True - RETURN_TYPES = ("STRING",) - FUNCTION = "notify" - OUTPUT_NODE = True - OUTPUT_IS_LIST = (True,) - - CATEGORY = "Data Analysis" - - MAX_NUM_ELEMENTS_TO_DISPLAY = 100 - - def notify(self, size: torch.Size, unique_id=None, extra_pnginfo=None): - text = str(size[0]) - - if unique_id is not None and extra_pnginfo is not None: - if not isinstance(extra_pnginfo, list): - print("Error: extra_pnginfo is not a list") - elif ( - not isinstance(extra_pnginfo[0], dict) - or "workflow" not in extra_pnginfo[0] - ): - print("Error: extra_pnginfo[0] is not a dict or missing 'workflow' key") - else: - workflow = extra_pnginfo[0]["workflow"] - node = next( - (x for x in workflow["nodes"] if str(x["id"]) == str(unique_id[0])), - None, - ) - if node: - node["widgets_values"] = [text] - else: - print("unique_id or extra_pnginfo is None.") - return {"ui": {"text": [text]}, "result": ([text],)} diff --git a/modules/pytorch_wrapper/pt_show_text.py b/modules/pytorch_wrapper/pt_show_text.py deleted file mode 100644 index 152db36..0000000 --- a/modules/pytorch_wrapper/pt_show_text.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -Almost all of this code was taken from -https://github.com/pythongosssss/ComfyUI-Custom-Scripts/blob/main/py/show_text.py - -See credit/credit.md for the full license. -""" -from typing import List -import torch - - -class PtShowText: - """ - Displays PyTorch tensor as a string. Note that the tensor is partially printed out when - the tensor contains more elements than the threshold set internally. - - category: Display data - """ - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "tens": ("TENSOR", {}), - }, - "hidden": { - "unique_id": "UNIQUE_ID", - "extra_pnginfo": "EXTRA_PNGINFO", - }, - } - - INPUT_IS_LIST = True - RETURN_TYPES = ("STRING",) - FUNCTION = "notify" - OUTPUT_NODE = True - OUTPUT_IS_LIST = (True,) - - CATEGORY = "Data Analysis" - - MAX_NUM_ELEMENTS_TO_DISPLAY = 100 - - def notify(self, tens: torch.Tensor, unique_id=None, extra_pnginfo=None): - torch.set_printoptions(threshold=PtShowText.MAX_NUM_ELEMENTS_TO_DISPLAY) - text = str(tens[0]) - - if unique_id is not None and extra_pnginfo is not None: - if not isinstance(extra_pnginfo, list): - print("Error: extra_pnginfo is not a list") - elif ( - not isinstance(extra_pnginfo[0], dict) - or "workflow" not in extra_pnginfo[0] - ): - print("Error: extra_pnginfo[0] is not a dict or missing 'workflow' key") - else: - workflow = extra_pnginfo[0]["workflow"] - node = next( - (x for x in workflow["nodes"] if str(x["id"]) == str(unique_id[0])), - None, - ) - if node: - node["widgets_values"] = [text] - else: - print("unique_id or extra_pnginfo is None.") - return {"ui": {"text": [text]}, "result": ([text],)} diff --git a/modules/pytorch_wrapper/pt_sin.py b/modules/pytorch_wrapper/pt_sin.py deleted file mode 100644 index fb25085..0000000 --- a/modules/pytorch_wrapper/pt_sin.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtSin: - """ - Computes the sine of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise sine of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type, representing angles in radians. - - Returns: - tuple: A tuple containing the resultant tensor after applying the sine function. - """ - return (torch.sin(tens_a),) diff --git a/modules/pytorch_wrapper/pt_sinh.py b/modules/pytorch_wrapper/pt_sinh.py deleted file mode 100644 index 5707082..0000000 --- a/modules/pytorch_wrapper/pt_sinh.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtSinh: - """ - Computes the hyperbolic sine of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise hyperbolic sine of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the hyperbolic sine function. - """ - return (torch.sinh(tens_a),) diff --git a/modules/pytorch_wrapper/pt_size.py b/modules/pytorch_wrapper/pt_size.py deleted file mode 100644 index dd3be36..0000000 --- a/modules/pytorch_wrapper/pt_size.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtSize: - """ - Extracts the PyTorch Size object of a PyTorch tensor using the size() method. - - category: PyTorch wrapper - Size object support - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR",), - } - } - - RETURN_TYPES: tuple = ("PTSIZE",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Extracts the PyTorch Size object of a PyTorch tensor using the size() method. - - Args: - tens (torch.Tensor): The tensor. - - Returns: - tuple: A tuple containing the PyTorch Size. - """ - return (tens.size(),) diff --git a/modules/pytorch_wrapper/pt_size_create.py b/modules/pytorch_wrapper/pt_size_create.py deleted file mode 100644 index c19b877..0000000 --- a/modules/pytorch_wrapper/pt_size_create.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtSizeCreate: - """ - Creates a PyTorch Size using values entered in the text field. - - category: PyTorch wrapper - Size object support - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "data": ("STRING", {"multiline": True}), - } - } - - RETURN_TYPES: tuple = ("PTSIZE",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, data: str) -> tuple: - """ - Creates a PyTorch Size using values entered in the text field. - - Args: - data (str): String value in the text field. - - Returns: - tuple: A tuple containing the PyTorch Size. - """ - # Convert string to Python list - list_data = ast.literal_eval(data) - - # Convert list to PyTorch Size - size = torch.Size(list_data) - return (size,) diff --git a/modules/pytorch_wrapper/pt_size_to_numpy.py b/modules/pytorch_wrapper/pt_size_to_numpy.py deleted file mode 100644 index eb8ce05..0000000 --- a/modules/pytorch_wrapper/pt_size_to_numpy.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch -import numpy as np - -class PtSizeToNumpy: - """ - Converts PyTorch Size object to NumPy ndarray. - - category: PyTorch wrapper - Size object support - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "sz": ("PTSIZE", {}), - } - } - - RETURN_TYPES: tuple = ("NDARRAY",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, sz: torch.Size) -> tuple: - """ - Converts PyTorch Size object to NumPy ndarray. - - Args: - sz (torch.Size): PyTorch Size - - Returns: - tuple: A tuple containing the ndarray. - """ - array = np.array(sz, dtype=int) - return (array,) diff --git a/modules/pytorch_wrapper/pt_size_to_string.py b/modules/pytorch_wrapper/pt_size_to_string.py deleted file mode 100644 index 8dc7992..0000000 --- a/modules/pytorch_wrapper/pt_size_to_string.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtSizeToString: - """ - Converts PyTorch Size object to a Python string. - - category: PyTorch wrapper - Size object support - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "sz": ("PTSIZE", {}), - } - } - - RETURN_TYPES: tuple = ("STRING",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, sz: torch.Size) -> tuple: - """ - Converts PyTorch Size object to a Python string. - - Args: - sz (torch.Size): PyTorch Size - - Returns: - tuple: A tuple containing the string. - """ - return (str(sz),) diff --git a/modules/pytorch_wrapper/pt_sqrt.py b/modules/pytorch_wrapper/pt_sqrt.py deleted file mode 100644 index b6b4514..0000000 --- a/modules/pytorch_wrapper/pt_sqrt.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtSqrt: - """ - Computes the square root of each element in a PyTorch tensor. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the square root of a PyTorch tensor element-wise. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the square root function. - """ - return (torch.sqrt(tens_a),) diff --git a/modules/pytorch_wrapper/pt_squeeze.py b/modules/pytorch_wrapper/pt_squeeze.py deleted file mode 100644 index c86f3ce..0000000 --- a/modules/pytorch_wrapper/pt_squeeze.py +++ /dev/null @@ -1,45 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import DTYPE_MAPPING - -class PtSqueeze: - """ - Removes a dimension at the specified position in the input tensor if it is of size 1. - - Specifying a tuple of dimensions is not supported yet. - - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("INT", {"default": -1, "min": -1, "max": 10}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: int) -> tuple: - """ - Removes a dimension at the specified position in the input tensor if it is of size 1. - - Args: - tens (torch.Tensor): Input tensor. - dim (int): Dimension to remove if it is of size 1. - - Returns: - tuple: A tuple containing the transformed PyTorch tensor. - """ - tens = torch.squeeze(tens, dim) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_std.py b/modules/pytorch_wrapper/pt_std.py deleted file mode 100644 index d6c78c9..0000000 --- a/modules/pytorch_wrapper/pt_std.py +++ /dev/null @@ -1,68 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtStd: - """ - Computes the standard deviation of a PyTorch tensor along the specified dimension(s). - - Specify 1 to use Bessel's correction (N-1) for sample standard deviation. - Specify 0 to compute population standard deviation. - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "correction": ("INT", {"default": 1, "min": 0, "max": 1}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, correction: int, keepdim: bool) -> tuple: - """ - Computes the standard deviation along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the standard deviation, - e.g., "0", "[0]", or "(1, 2)". - correction (int): 0 for population standard deviation, 1 for sample standard deviation (Bessel's correction). - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the standard deviation tensor. - """ - dim = str_to_dim(dim) - - # Ensure correction is valid (0 or 1) - if correction not in (0, 1): - raise ValueError(f"Invalid correction value: {correction}. Must be 0 (population) or 1 (sample).") - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the standard deviation along the specified dimension(s) - tens = torch.std(tens, dim=dim, correction=correction, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_sub.py b/modules/pytorch_wrapper/pt_sub.py deleted file mode 100644 index 026b0b1..0000000 --- a/modules/pytorch_wrapper/pt_sub.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - -class PtSub: - """ - Subtracts one PyTorch tensor from another. - - category: PyTorch wrapper - Arithmetic operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}), - "tens_b": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor, tens_b: torch.Tensor) -> tuple: - """ - Subtracts one PyTorch tensor from another. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of any shape. - tens_b (torch.Tensor): A PyTorch tensor of shape that supports subtraction from `tens_a`. - - Returns: - tuple: A tuple containing the resultant tensor. - """ - return (torch.sub(tens_a, tens_b),) diff --git a/modules/pytorch_wrapper/pt_sum.py b/modules/pytorch_wrapper/pt_sum.py deleted file mode 100644 index 9b43c1e..0000000 --- a/modules/pytorch_wrapper/pt_sum.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtSum: - """ - Computes the sum of a PyTorch tensor along the specified dimension(s). - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, keepdim: bool) -> tuple: - """ - Computes the sum along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the sum, - e.g., "0", "[0]", or "(1, 2)". - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the summed tensor. - """ - dim = str_to_dim(dim) - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the sum along the specified dimension(s) - tens = torch.sum(tens, dim=dim, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_tan.py b/modules/pytorch_wrapper/pt_tan.py deleted file mode 100644 index 0f38135..0000000 --- a/modules/pytorch_wrapper/pt_tan.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtTan: - """ - Computes the tangent of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise tangent of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type, representing angles in radians. - - Returns: - tuple: A tuple containing the resultant tensor after applying the tangent function. - """ - return (torch.tan(tens_a),) diff --git a/modules/pytorch_wrapper/pt_tanh.py b/modules/pytorch_wrapper/pt_tanh.py deleted file mode 100644 index 9e08aca..0000000 --- a/modules/pytorch_wrapper/pt_tanh.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Dict -import torch - -class PtTanh: - """ - Computes the hyperbolic tangent of a PyTorch tensor element-wise. - - category: PyTorch wrapper - Math operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens_a": ("TENSOR", {}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens_a: torch.Tensor) -> tuple: - """ - Computes the element-wise hyperbolic tangent of a PyTorch tensor. - - Args: - tens_a (torch.Tensor): A PyTorch tensor of numerical type. - - Returns: - tuple: A tuple containing the resultant tensor after applying the hyperbolic tangent function. - """ - return (torch.tanh(tens_a),) diff --git a/modules/pytorch_wrapper/pt_to_image.py b/modules/pytorch_wrapper/pt_to_image.py deleted file mode 100644 index cd3ddb4..0000000 --- a/modules/pytorch_wrapper/pt_to_image.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtToImage: - """ - Casts a PyTorch tensor as an Image tensor. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_NAMES: tuple = ("image",) - RETURN_TYPES: tuple = ("IMAGE",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Casts a PyTorch tensor as an Image tensor. - - Args: - tens (torch.Tensor): PyTorch Tensor - - Returns: - tuple: A tuple containing the image tensor. - """ - return (tens,) diff --git a/modules/pytorch_wrapper/pt_to_image_transpose.py b/modules/pytorch_wrapper/pt_to_image_transpose.py deleted file mode 100644 index 3218dbc..0000000 --- a/modules/pytorch_wrapper/pt_to_image_transpose.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtToImageTranspose: - """ - Casts a PyTorch tensor as an Image tensor and transposes it from (C, H, W) to (H, W, C). For rank-4 inputs, the batch axis remains unchanged. - - category: PyTorch wrapper - Image processing - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_NAMES: tuple = ("image",) - RETURN_TYPES: tuple = ("IMAGE",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Casts a PyTorch tensor as an Image tensor. - - Args: - tens (torch.Tensor): PyTorch Tensor - - Returns: - tuple: A tuple containing the image tensor. - """ - if tens.dim() == 3: - image = tens.permute(1, 2, 0) - elif tens.dim() == 4: - image = tens.permute(0, 2, 3, 1) - else: - raise ValueError("Only rank 3 or 4 tensors are supported.") - return (image,) diff --git a/modules/pytorch_wrapper/pt_to_latent.py b/modules/pytorch_wrapper/pt_to_latent.py deleted file mode 100644 index b9a7fb2..0000000 --- a/modules/pytorch_wrapper/pt_to_latent.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtToLatent: - """ - Casts a PyTorch tensor as a latent tensor. - - category: PyTorch wrapper - Tensor data conversion - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_TYPES: tuple = ("LATENT",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Casts a PyTorch tensor as a latent tensor. - - Args: - tens (torch.Tensor): PyTorch Tensor - - Returns: - tuple: A tuple containing the latent tensor. - """ - return ({"samples":tens},) diff --git a/modules/pytorch_wrapper/pt_to_numpy.py b/modules/pytorch_wrapper/pt_to_numpy.py deleted file mode 100644 index 4b2b9b7..0000000 --- a/modules/pytorch_wrapper/pt_to_numpy.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtToNumpy: - """ - Converts PyTorch tensor to NumPy ndarray. - - category: PyTorch wrapper - Tensor data conversion - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_TYPES: tuple = ("NDARRAY",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Converts PyTorch tensor to NumPy ndarray. - - Args: - tens (torch.Tensor): PyTorch Tensor - - Returns: - tuple: A tuple containing the ndarray. - """ - array = tens.cpu().detach().numpy() - return (array,) diff --git a/modules/pytorch_wrapper/pt_to_rgb_tensors.py b/modules/pytorch_wrapper/pt_to_rgb_tensors.py deleted file mode 100644 index a162129..0000000 --- a/modules/pytorch_wrapper/pt_to_rgb_tensors.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtToRgbTensors: - """ - Splits a PyTorch tensor into R, G, and B tensors. - - category: PyTorch wrapper - Tensor data conversion - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - } - } - - RETURN_NAMES: tuple = ("R", "G", "B") - RETURN_TYPES: tuple = ("TENSOR", "TENSOR", "TENSOR") - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor) -> tuple: - """ - Splits a PyTorch tensor into R, G, and B tensors. - - Args: - tens (torch.Tensor): A PyTorch tensor of shape [B, H, W, C] or [H, W, C]. - Assumes the last axis represents the color channels. - - Returns: - tuple: A tuple containing the R, G, and B tensors. - If the input tensor has a batch axis, it will be retained. - - Raises: - ValueError: If the input tensor does not have exactly 3 channels. - """ - if tens.size()[-1] != 3: - raise ValueError(f"Expected a 3-channel tensor, but got {tens.size()[-1]} channels.") - - r, g, b = tens[..., 0], tens[..., 1], tens[..., 2] - return (r, g, b) diff --git a/modules/pytorch_wrapper/pt_train_classification_model.py b/modules/pytorch_wrapper/pt_train_classification_model.py deleted file mode 100644 index 75700c9..0000000 --- a/modules/pytorch_wrapper/pt_train_classification_model.py +++ /dev/null @@ -1,122 +0,0 @@ -from typing import Any, Dict, Optional, Tuple -import torch -import torch.nn as nn -import torch.nn.functional as F -import numpy as np - -class PtTrainClassificationModel: - """ - Trains a classification model using a given dataset, optimizer, and number of epochs. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types required for training the model. - - Returns: - Dict[str, Any]: A dictionary specifying required and optional input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "train_loader": ("PTDATALOADER", {}), - "optimizer": ("PTOPTIMIZER", {}), - "epochs": ("INT", {"default":1, "min":1, "max":1e6}), - "use_gpu": ("BOOLEAN", {"default":False}) - }, - "optional": { - "val_loader": ("PTDATALOADER", {}), - } - } - - RETURN_NAMES: tuple = ("Model", "train loss", "val loss") - RETURN_TYPES: tuple = ("PTMODEL","TENSOR","TENSOR") - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, model: nn.Module, - train_loader: torch.utils.data.DataLoader, - optimizer: torch.optim.Optimizer, - epochs: int, - use_gpu: bool, - val_loader: Optional[torch.utils.data.DataLoader] = None) -> Tuple[nn.Module, torch.Tensor, torch.Tensor]: - """ - Trains a classification model. - - Args: - model (torch.nn.Module): The PyTorch model to be trained. - train_loader (torch.utils.data.DataLoader): DataLoader containing the training dataset. - optimizer (torch.optim.Optimizer): Optimizer used for training. - epochs (int): Number of training epochs. - use_gpu (bool): Whether to use GPU for training. - val_loader (Optional[torch.utils.data.DataLoader]): DataLoader for validation dataset (optional). - - Returns: - Tuple[torch.nn.Module, torch.Tensor, torch.Tensor]: A tuple containing the trained model, - training loss history, and validation loss history. - """ - - with torch.inference_mode(False): - train_loss = [] - val_loss = [] - if use_gpu: - model.to("cuda") - - loss_function = nn.CrossEntropyLoss() # mean loss - - # Train the model - for epoch in range(epochs): - model.train() - total_loss = 0 - total_samples = len(train_loader.dataset) - for images, labels in train_loader: - if use_gpu: - images = images.to("cuda") - labels = labels.to("cuda") - optimizer.zero_grad() - outputs = model(images) - loss = loss_function(outputs, labels) - loss.backward() - optimizer.step() - - batch_size = labels.size(0) - batch_loss = loss.item() * batch_size - total_loss += batch_loss - - epoch_loss = total_loss / total_samples - - print(f"Epoch (train) {epoch+1}/{epochs}, Loss: {epoch_loss:.4f}") - train_loss.append(epoch_loss) - - if val_loader: - with torch.no_grad(): - model.train(False) # TODO: Change to model.*e*v*a*l() once Comfy's security checker is fixed. - total_loss = 0 - total_samples = len(val_loader.dataset) - for images, labels in val_loader: - if use_gpu: - images = images.to("cuda") - labels = labels.to("cuda") - outputs = model(images) - loss = loss_function(outputs, labels) - batch_size = labels.size(0) - batch_loss = loss.item() * batch_size - total_loss += batch_loss - - epoch_loss = total_loss / total_samples - print(f"Epoch (val) {epoch+1}/{epochs}, Loss: {epoch_loss:.4f}") - val_loss.append(epoch_loss) - - if use_gpu: - model.to("cpu") - - return (model, - torch.tensor(train_loss, dtype=torch.float32), - torch.tensor(val_loss, dtype=torch.float32)) \ No newline at end of file diff --git a/modules/pytorch_wrapper/pt_unsqueeze.py b/modules/pytorch_wrapper/pt_unsqueeze.py deleted file mode 100644 index 7505b95..0000000 --- a/modules/pytorch_wrapper/pt_unsqueeze.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import Any, Dict -import torch - - -class PtUnsqueeze: - """ - Adds a singleton dimension at the specified position in the input tensor. - For example, if a tensor has shape (3, 4) and `dim=1`, the output will have shape (3, 1, 4). - - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "dim": ("INT", {"default": -1, "min": -10, "max": 10}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: int) -> tuple: - """ - Adds a singleton dimension at the specified position. - - Args: - tens (torch.Tensor): Input tensor. - dim (int): Dimension at which to insert the new singleton dimension. - - Returns: - tuple: A tuple containing the transformed PyTorch tensor. - """ - tens = torch.unsqueeze(tens, dim) - return (tens,) diff --git a/modules/pytorch_wrapper/pt_var.py b/modules/pytorch_wrapper/pt_var.py deleted file mode 100644 index 56829c0..0000000 --- a/modules/pytorch_wrapper/pt_var.py +++ /dev/null @@ -1,68 +0,0 @@ -from typing import Any, Dict -import torch -from .utils import str_to_dim - - -class PtVar: - """ - Computes the variance of a PyTorch tensor along the specified dimension(s). - - Specify 1 to use Bessel's correction (N-1) for sample variance. - Specify 0 to compute population variance. - - Specify the dimension(s) in the `dim` field using an integer, a list, or a tuple, as shown below: - ``` - 0, [0], or (1, 2) - ``` - category: PyTorch wrapper - Reduction operation & Summary statistics - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "correction": ("INT", {"default": 1, "min": 0, "max": 1}), - "dim": ("STRING", {"multiline": True}), - "keepdim": ("BOOLEAN", {"default": False}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, dim: str, correction: int, keepdim: bool) -> tuple: - """ - Computes the variance along the specified dimension(s). - - Args: - tens (torch.Tensor): The input tensor. - dim (str): A string representation of the dimension(s) along which to compute the variance, - e.g., "0", "[0]", or "(1, 2)". - correction (int): 0 for population variance, 1 for sample variance (Bessel's correction). - keepdim (bool): Whether to retain reduced dimensions. - - Returns: - tuple: A tuple containing the variance tensor. - """ - dim = str_to_dim(dim) - - # Ensure correction is valid (0 or 1) - if correction not in (0, 1): - raise ValueError(f"Invalid correction value: {correction}. Must be 0 (population) or 1 (sample).") - - # Ensure keepdim is a boolean - if not isinstance(keepdim, bool): - raise TypeError(f"Invalid type for keepdim: {keepdim}. Must be a boolean.") - - # Compute the variance along the specified dimension(s) - tens = torch.var(tens, dim=dim, correction=correction, keepdim=keepdim) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_view.py b/modules/pytorch_wrapper/pt_view.py deleted file mode 100644 index 3d7de7d..0000000 --- a/modules/pytorch_wrapper/pt_view.py +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Dict -import torch -import ast - - -class PtView: - """ - Reshapes a PyTorch tensor into a specified shape using `torch.view()`. - The total number of elements must remain unchanged. - - For example, if a tensor has shape (2, 3, 4), and `new_shape="[6, 4]"`, - the output will have shape (6, 4). - - Use -1 to automatically infer a dimension, e.g.: - ``` - [2, -1] - ``` - category: PyTorch wrapper - Transform - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "tens": ("TENSOR", {}), - "new_shape": ("STRING", {"multiline": True}) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, tens: torch.Tensor, new_shape: str) -> tuple: - """ - Reshapes the input tensor based on the specified shape. - - Args: - tens (torch.Tensor): The input tensor. - new_shape (str): A string representation of the desired shape, - e.g., "[2, -1]" or "(6, 4)". - - Returns: - tuple: A tuple containing the reshaped PyTorch tensor. - """ - # Convert string to a tuple of integers - shape_order = tuple(ast.literal_eval(new_shape)) - - # Ensure the parsed shape is valid - if not isinstance(shape_order, tuple) or not all(isinstance(i, int) for i in shape_order): - raise ValueError(f"Invalid format for new_shape: {new_shape}. Must be a tuple or list of integers.") - - # Apply view operation - tens = tens.view(*shape_order) - - return (tens,) diff --git a/modules/pytorch_wrapper/pt_where.py b/modules/pytorch_wrapper/pt_where.py deleted file mode 100644 index 7635af4..0000000 --- a/modules/pytorch_wrapper/pt_where.py +++ /dev/null @@ -1,61 +0,0 @@ -from typing import Any, Dict -import torch - -class PtWhere: - """ - Generates a new tensor by selecting values based on a condition tensor. - - * `condition_tens` (torch.Tensor): Boolean tensor that determines which values are selected. - * `true_tens` (torch.Tensor): Values to use where the condition is `True`. - * `false_tens` (torch.Tensor): Values to use where the condition is `False`. - - category: PyTorch wrapper - Indexing and Slicing Operations - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "condition_tens": ("TENSOR", {}), - "true_tens": ("TENSOR", {}), - "false_tens": ("TENSOR", {}), - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, - condition_tens: torch.Tensor, - true_tens: torch.Tensor, - false_tens: torch.Tensor) -> tuple: - """ - Selects values from `true_tens` or `false_tens` based on `condition_tens`. - - Args: - condition_tens (torch.Tensor): Boolean tensor indicating selection conditions. - true_tens (torch.Tensor): Values used where condition is True. - false_tens (torch.Tensor): Values used where condition is False. - - Returns: - tuple: A tuple containing the modified tensor. - """ - # Ensure condition_tens is a boolean tensor - if condition_tens.dtype != torch.bool: - raise TypeError(f"Expected `condition_tens` to be a boolean tensor, got {condition_tens.dtype}") - - # Ensure all tensors are compatible in shape - if not torch.broadcast_shapes(condition_tens.shape, true_tens.shape, false_tens.shape): - raise ValueError(f"Shape mismatch: condition {condition_tens.shape}, true {true_tens.shape}, false {false_tens.shape}") - - # Perform the conditional selection - tens_out = torch.where(condition_tens, true_tens, false_tens) - - return (tens_out,) diff --git a/modules/pytorch_wrapper/pt_zeros.py b/modules/pytorch_wrapper/pt_zeros.py deleted file mode 100644 index 0eeacc0..0000000 --- a/modules/pytorch_wrapper/pt_zeros.py +++ /dev/null @@ -1,52 +0,0 @@ -from typing import Any, Dict -import torch -import ast -from .utils import DTYPE_MAPPING - -class PtZeros: - """ - Creates a PyTorch tensor of zeros using the size entered in the text field. - For example, if you want to create a 4D tensor of batch size=2, channel=3, height=96, width=32, enter: - [2,3,96,32] - - category: PyTorch wrapper - Tensor creation - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "size": ("STRING", {"multiline": True}), - "data_type": (("float32", "float16", "bfloat16", "float64", "uint8", "int8", "int16", "int32", "int64", "bool"),) - } - } - - RETURN_TYPES: tuple = ("TENSOR",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, size: str, data_type: str) -> tuple: - """ - Creates a PyTorch tensor of zeros using the size entered in the text field. - - Args: - size (str): String value in the text field. - data_type (str): Desired data type of the tensor. - - Returns: - tuple: A tuple containing the PyTorch tensor. - """ - # Convert string to Python list - list_size = ast.literal_eval(size) - - # Convert list to PyTorch Size - sz = torch.Size(list_size) - tens = torch.zeros(sz, dtype=DTYPE_MAPPING[data_type]) - - return (tens,) diff --git a/modules/pytorch_wrapper/ptn_conv_model.py b/modules/pytorch_wrapper/ptn_conv_model.py deleted file mode 100644 index a31fe36..0000000 --- a/modules/pytorch_wrapper/ptn_conv_model.py +++ /dev/null @@ -1,99 +0,0 @@ -from typing import Any, Dict, Tuple -import ast -import torch -from .ptn_conv_model_def import ConvModel - - -class PtnConvModel: - """ - A convolutional model consisting of multiple convolutional layers. - - ### Fields: - - `input_dim`: A string representing the input dimensions in the format "(C,H,W)". - Example: `"(3,28,28)"` for a 3-channel 28x28 image. - - - `penultimate_dim`: An integer specifying the number of features before the output layer. If you specify 0, the number is computed internally. - Default: `0` - - - `output_dim`: An integer specifying the number of output features, which should match the number of target classes in classification. - Default: `10`, Min: `1`, Max: `1e6`. - - - `channel_list`: A string representing a Python list of integers specifying the number of channels per layer excluding the channel for the input (e.g. 3 for the color image). - Example: `"[32,64,128,256,512]"`. - - - `kernel_size_list`: A string representing a Python list of kernel sizes per layer. - Example: `"[3,3,3,3,1]"`. - - - `padding_list`: A string representing a Python list of padding values per layer. - Example: `"[1,1,1,1,0]"`. - - - `downsample_list`: A string representing a Python list of boolean values indicating whether to downsample at each layer. - Example: `"[True,True,True,True,False]"`. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "input_dim": ("STRING", {"default": "(3,28,28)"}), - "penultimate_dim": ("INT", {"default": 0, "min": 0, "max": 1e6}), - "output_dim": ("INT", {"default": 10, "min": 1, "max": 1e6}), - "channel_list": ("STRING", {"default": "[32,64,128,256,512]"}), - "kernel_size_list": ("STRING", {"default": "[3,3,3,3,1]"}), - "padding_list": ("STRING", {"default": "[1,1,1,1,0]"}), - "downsample_list": ("STRING", {"default": "[True,True,True,True,False]"}) - } - } - - RETURN_TYPES: Tuple[str] = ("PTMODEL",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, - input_dim:str, - penultimate_dim: int, - output_dim: int, - channel_list: str, - kernel_size_list: str, - padding_list: str, - downsample_list: str) -> None: - """ - Constructs a convolutional neural network model. - - Args: - TODO:Update - - Returns: - Tuple[nn.Module]: A tuple containing the instantiated PyTorch model. - - Raises: - TODO:Update - """ - input_dim_parsed = tuple(ast.literal_eval(input_dim)) - channel_list_parsed = ast.literal_eval(channel_list) - kernel_size_list_parsed = ast.literal_eval(kernel_size_list) - padding_list_parsed = ast.literal_eval(padding_list) - downsample_list_parsed = ast.literal_eval(downsample_list) - - with torch.inference_mode(False): - model = ConvModel( - input_dim_parsed, - penultimate_dim, - output_dim, - channel_list_parsed, - kernel_size_list_parsed, - padding_list_parsed, - downsample_list_parsed) - return (model,) diff --git a/modules/pytorch_wrapper/ptn_conv_model_def.py b/modules/pytorch_wrapper/ptn_conv_model_def.py deleted file mode 100644 index 74f71c6..0000000 --- a/modules/pytorch_wrapper/ptn_conv_model_def.py +++ /dev/null @@ -1,151 +0,0 @@ -from typing import List, Dict, Any, Tuple -import torch -import torch.nn as nn - - -class ConvSingleLayer(nn.Module): - """A single convolutional layer followed by an optional ReLU activation and optional downsampling. - - Shape is tensor of shape `(batch_size, in_channels, height, width)`. - - Args: - in_channels (int): Number of input channels. - out_channels (int): Number of output channels. - kernel_size (int): Size of the convolutional kernel. - padding (int): Padding size for convolution. - downsample (bool): If True, applies a 2x2 MaxPooling layer. - apply_activation (bool, optional): If True, applies ReLU activation. Defaults to True. - - pragma: skip_doc - """ - - @classmethod # TODO: Dummy method to suppress ComfyUI warning. DO NOT REMOVE - def INPUT_TYPES(cls) -> Dict[str, Any]: - return {} - - def __init__(self, - in_channels: int, - out_channels: int, - kernel_size: int, - padding: int, - downsample: bool, - apply_activation: bool = True) -> None: - super().__init__() - self.conv = nn.Conv2d(in_channels=in_channels, - out_channels=out_channels, - kernel_size=kernel_size, - padding=padding) - self.apply_activation = apply_activation - self.activation = nn.ReLU() - self.downsample = downsample - self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2) - - def forward(self, inputs: torch.Tensor) -> torch.Tensor: - """Forward pass of the convolutional layer. - - Args: - inputs (torch.Tensor): Input tensor of shape `(batch_size, in_channels, height, width)`. - - Returns: - torch.Tensor: Output tensor after convolution, optional activation, and optional pooling. - """ - x = self.conv(inputs) - if self.downsample: - x = self.maxpool(x) - if self.apply_activation: - x = self.activation(x) - return x - - -class ConvModel(nn.Module): - """A multi-layer convolutional neural network with ReLU activation after each convolutional layer, except for the final dense layer. - - Args: - input_dim (Tuple[int, int, int]): Shape of a single input sample (C, H, W). - penultimate_dim (int): Number of features before the final dense layer. If 0 is specified, this value is automatically computed internally. - output_dim (int): Number of output features. - channel_list (List[int]): List of channel sizes for each layer. This should not include the inputs channel. - Input channel is taken from the first element of input_dim. - kernel_size_list (List[int]): List of kernel sizes for each convolutional layer. - padding_list (List[int]): List of padding values for each convolutional layer. - downsample_list (List[bool]): List indicating whether downsampling should be applied after each layer. - - pragma: skip_doc - """ - - @classmethod # TODO: Dummy method to suppress ComfyUI warning - def INPUT_TYPES(cls) -> Dict[str, Any]: - return {} - - def __init__(self, - input_dim: Tuple[int, int, int], - penultimate_dim: int, - output_dim: int, - channel_list: List[int], - kernel_size_list: List[int], - padding_list: List[int], - downsample_list: List[bool]) -> None: - super().__init__() - - # Validate list lengths - if (len(channel_list) != len(kernel_size_list) or - len(kernel_size_list) != len(padding_list) or - len(padding_list) != len(downsample_list)): - raise ValueError("channel_list, kernel_size_list, padding_list, and downsample_list must have the same length.") - - self.channel_list = [input_dim[0]] + channel_list - - # Initialize convolutional layers - layers = [] - for i in range(len(self.channel_list) - 1): - layers.append( - ConvSingleLayer( - in_channels=self.channel_list[i], - out_channels=self.channel_list[i + 1], - kernel_size=kernel_size_list[i], - padding=padding_list[i], - downsample=downsample_list[i] - ) - ) - - self.conv_layers = nn.ModuleList(layers) - - if penultimate_dim == 0: - # Try to auto compute penultimate_dim by processing the dummy input - with torch.no_grad(): - dummy_input = torch.randn(1, *input_dim) # B, C, H, W - x = dummy_input - for layer in self.conv_layers: - x = layer(x) - checked_penultimate_dim = x.numel() # Number of elements - else: - checked_penultimate_dim = penultimate_dim - - self.final_dense = nn.Linear(checked_penultimate_dim, output_dim, bias=True) - - def forward(self, inputs: torch.Tensor) -> torch.Tensor: - """Forward pass of the model. - - Args: - inputs (torch.Tensor): Input tensor of shape `(batch_size, C, H, W)`. - - Returns: - torch.Tensor: Output tensor of shape `(batch_size, output_dim)`. - - Raises: - ValueError: If inputs is not a rank 4 tensor. - """ - if inputs.dim() not in [3, 4]: - raise ValueError("Inputs is not a rank 3 or 4 tensor.") - - if inputs.dim() == 3: - x = torch.unsqueeze(inputs, 1) - else: - x = inputs - - for layer in self.conv_layers: - x = layer(x) - - x = torch.flatten(x, start_dim=1) # Flatten except batch-axis - x = self.final_dense(x) - return x diff --git a/modules/pytorch_wrapper/ptn_linear_model.py b/modules/pytorch_wrapper/ptn_linear_model.py deleted file mode 100644 index bd2108e..0000000 --- a/modules/pytorch_wrapper/ptn_linear_model.py +++ /dev/null @@ -1,87 +0,0 @@ -from typing import Any, Dict, Tuple -import ast -import torch -import torch.nn as nn -from .ptn_linear_model_def import DenseModel - - -class PtnLinearModel: - """ - A linear model consisting of dense layers. - - ### Fields: - - `dim_list`: A string representing a Python list of layer dimensions. - It should contain the input dimension for the first layer and the output dimensions - for all layers. - - Example for a two-layer network: - - Input data: 784 - - Layer 1: 784 → 128 - - Layer 2: 128 → 10 - - Specify `"[784,128,10]"` - - - `bias_list`: A string representing a Python list of bias usage (True/False) per layer. - Example: "[True,False]" - - - `num_layers`: The number of layers in the model. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "dim_list": ("STRING", {"default": "784,10"}), - "bias_list": ("STRING", {"default": "{True}"}), - "num_layers": ("INT", {"default": 1, "min": 1, "max": 2000}), - } - } - - RETURN_TYPES: Tuple[str] = ("PTMODEL",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, dim_list: str, bias_list: str, num_layers: int) -> Tuple[nn.Module]: - """ - Constructs a dense neural network model. - - Args: - dim_list (str): A comma-separated string representing layer dimensions. - bias_list (str): A comma-separated string representing bias usage (True/False) per layer. - num_layers (int): The number of layers in the model. - - Returns: - Tuple[nn.Module]: A tuple containing the instantiated PyTorch model. - - Raises: - ValueError: If `dim_list` length does not match `num_layers + 1`. - ValueError: If `bias_list` length does not match `num_layers`. - """ - dims = ast.literal_eval(dim_list) - biases = ast.literal_eval(bias_list) - - if len(dims) - 1 != num_layers: - raise ValueError( - "dim_list and num_layers do not match. dim_list should contain " - "the input dimension for the first layer and output dimensions for all layers. " - "This list should be one element longer than the number of layers." - ) - - if len(biases) != num_layers: - raise ValueError("bias_list and num_layers do not match.") - - with torch.inference_mode(False): - model = DenseModel(dims, biases, num_layers) - - return (model,) diff --git a/modules/pytorch_wrapper/ptn_linear_model_def.py b/modules/pytorch_wrapper/ptn_linear_model_def.py deleted file mode 100644 index 28a10e6..0000000 --- a/modules/pytorch_wrapper/ptn_linear_model_def.py +++ /dev/null @@ -1,99 +0,0 @@ -from typing import List, Dict, Any -import torch -import torch.nn as nn - - -class DenseSingleLayer(nn.Module): - """A single dense layer followed by a ReLU activation. - - Args: - in_features (int): Number of input features. - out_features (int): Number of output features. - bias (bool): If True, adds a learnable bias to the layer. - - pragma: skip_doc - """ - - @classmethod # TODO: Dummy method to suppress ComfyUI warning - def INPUT_TYPES(cls) -> Dict[str, Any]: - return { - } - - def __init__(self, in_features: int, out_features: int, bias: bool) -> None: - super().__init__() - self.fc = nn.Linear(in_features, out_features, bias) - self.activation = nn.ReLU() - - def forward(self, inputs: torch.Tensor) -> torch.Tensor: - """Forward pass of the dense layer with ReLU activation. - - Args: - inputs (torch.Tensor): Input tensor of shape `(batch_size, in_features)`. - - Returns: - torch.Tensor: Output tensor of shape `(batch_size, out_features)`. - """ - x = self.fc(inputs) - x = self.activation(x) - return x - - -class DenseModel(nn.Module): - """A multi-layer dense neural network with ReLU activation after each dense layer, except for the final layer. - - Args: - dim_list (List[int]): List of feature dimensions. Should be of length `num_layers + 1`. - bias_list (List[bool]): List indicating whether each layer should have a bias. - num_layers (int): Number of layers in the model. - - Example: - For a three-layer network: - - Layer 1: input -> output1 - - Layer 2: output1 -> output2 - - Layer 3: output2 -> output3 - - `dim_list = [input_dim, output1_dim, output2_dim, output3_dim]` - - pragma: skip_doc - """ - - @classmethod # TODO: Dummy method to suppress ComfyUI warning - def INPUT_TYPES(cls) -> Dict[str, Any]: - return { - } - - def __init__(self, dim_list: List[int], bias_list: List[bool], num_layers: int) -> None: - super().__init__() - - self.no_activation_layers = nn.ModuleList([ - DenseSingleLayer(dim_list[i], dim_list[i + 1], bias_list[i]) - for i in range(num_layers - 1) - ]) - - self.dim_list = dim_list - self.bias_list = bias_list - self.num_layers = num_layers - - self.final_dense = nn.Linear( - dim_list[num_layers - 1], # in_features - dim_list[num_layers], # out_features - bias_list[num_layers - 1] - ) - - def forward(self, inputs: torch.Tensor) -> torch.Tensor: - """Forward pass of the dense model. - - Args: - inputs (torch.Tensor): Input tensor of shape `(batch_size, dim_list[0])`. - - Returns: - torch.Tensor: Output tensor of shape `(batch_size, dim_list[-1])`. - """ - x = inputs.view(-1, self.dim_list[0]) # Ensure correct input shape - - for i in range(self.num_layers - 1): - x = self.no_activation_layers[i](x) - - x = self.final_dense(x) - - return x diff --git a/modules/pytorch_wrapper/pto_adam.py b/modules/pytorch_wrapper/pto_adam.py deleted file mode 100644 index ddc1c1a..0000000 --- a/modules/pytorch_wrapper/pto_adam.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Any, Dict -import torch -import torch.nn as nn -import torch.nn.functional as F - -class PtoAdam: - """ - Instantiates the Adam optimizer. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the input types for the function. - - Returns: - Dict[str, Any]: A dictionary specifying required input types. - """ - return { - "required": { - "model": ("PTMODEL", {}), - "learning_rate": ("FLOAT", {"default":0.001, "min":1e-10, "max":1, "step":0.0000000001}), - "beta1": ("FLOAT", {"default":0.9, "min":1e-10, "max":1, "step":0.0000000001}), - "beta2": ("FLOAT", {"default":0.999, "min":1e-10, "max":1, "step":0.0000000001}), - } - } - - RETURN_TYPES: tuple = ("PTOPTIMIZER",) - FUNCTION: str = "f" - CATEGORY: str = "Data Analysis" - - def f(self, model, learning_rate, beta1, beta2) -> tuple: - """ - Converts PyTorch tensor to NumPy ndarray. - - Args: - tens (torch.Tensor): PyTorch Tensor - - Returns: - tuple: A tuple containing the ndarray. - """ - with torch.inference_mode(False): - opt = torch.optim.Adam(model.parameters(), lr=learning_rate, betas=(beta1, beta2)) - return(opt,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/ptv_dataset.py b/modules/pytorch_wrapper/ptv_dataset.py deleted file mode 100644 index 29984fd..0000000 --- a/modules/pytorch_wrapper/ptv_dataset.py +++ /dev/null @@ -1,124 +0,0 @@ -import inspect -from typing import Any, Dict, Optional, Callable, Tuple -import torch -import torchvision.datasets as datasets -import ast - -from .utils import get_dataset_full_path - -class PtvDataset: - """ - A Torchvision Dataset class wrapper. - - Parameters - - **name** - Specify a dataset class name such as MNIST, FashionMNIST in string. - This will be converted to a dataset class internally. - - **download** - Set to True if you want to download. - - **root** - Specify the root directory of the downloaded dataset relative to the - dataset directory of this extension, or specify the absolute path. - If you leave as a blank, the dataset will be downloaded under the `datasets` directory - of this extension. - - **transform** - Data transforms e.g. transform to PyTorch tensor, normalize image. - Plug in the PTV Transforms node that contains Torchvision Transforms functionality. - - **parameters** - Specify other parameters in Python dict format. - For example, if you want to set Train parameter to True to download the train set, specify: - ``` - {"train": True} - ``` - or if you want to download the test set, specify: - ``` - {"train": False} - ``` - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "name": ("STRING", {"default": "", "multiline": False}), - "download": ("BOOLEAN", {"default": True}), - "root": ("STRING", {"default": "", "multiline": False}), - }, - "optional": { - "transform": ("PTVTRANSFORM", {}), - "parameters": ("STRING", {"default": "", "multiline": True}) - } - } - - RETURN_TYPES: Tuple[str] = ("PTVDATASET",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, - name: str, - download: bool, - root: str, - parameters: str, - transform: Optional[Callable] = None) -> Tuple: - """ - Loads a dataset from Torchvision with specified parameters. - - Args: - name (str): Name of the dataset class (e.g., MNIST, FashionMNIST). - download (bool): Whether to download the dataset. - root (str): Root directory for storing the dataset. - parameters (str): Additional dataset parameters in stringified dictionary format. - transform (Optional[Callable]): Transformations to apply to the dataset. - - Returns: - Tuple: A tuple containing the dataset instance. - """ - - with torch.inference_mode(False): - param_dict = ast.literal_eval(parameters) - - # Converts the datasets class name to dataset class itself - try: - dataset_class = getattr(datasets, name) - except AttributeError: - raise ValueError(f"Dataset '{name}' is not available in torchvision.datasets") - - # Get valid parameters for the dataset class - valid_params = inspect.signature(dataset_class).parameters - - # Filter only parameters that match the dataset's constructor - filtered_params = {k: v for k, v in param_dict.items() if k in valid_params} - - if root: - dataset_path = get_dataset_full_path(root) - else: # Use default directory - dataset_path = get_dataset_full_path("") - - if transform: - dc = dataset_class(download=download, - root=dataset_path, - transform=transform, - **filtered_params) - else: - dc = dataset_class(download=download, - root=dataset_path, - **filtered_params) - - return (dc,) diff --git a/modules/pytorch_wrapper/ptv_dataset_loader.py b/modules/pytorch_wrapper/ptv_dataset_loader.py deleted file mode 100644 index 40ad553..0000000 --- a/modules/pytorch_wrapper/ptv_dataset_loader.py +++ /dev/null @@ -1,148 +0,0 @@ -import ast -import inspect -from typing import Any, Dict, Tuple -import torch -import torchvision.datasets as datasets -from torch.utils.data import DataLoader -import torchvision.transforms as transforms -from .utils import get_dataset_full_path - - -class PtvDatasetLoader: - """ - A node to combine the dataset and data loader into a single node. - - Transform is internally called to convert input data to PyTorch tensors. - - Parameters - - **name** - Specify the dataset class name such as MNIST, FashionMNIST in string. - This will be converted to a dataset class internally. - - **download** - Set to True if you want to download. - - **root** - Specify the root directory of the downloaded dataset relative to the - dataset directory of this extension, or specify the absolute path. - If you leave as a blank, the dataset will be downloaded under the `datasets` directory - of this extension. - - **batch_size** - The number of samples per batch. - - **shuffle** - If True, shuffles the dataset before each epoch. - - **dataset parameters** - Specify other parameters in Python dict format. - For example, if you want to set Train parameter to True to download the train set, specify: - ``` - {"train": True} - ``` - or if you want to download the test set, specify: - ``` - {"train": False} - ``` - - **load parameters** - Additional parameters in Python dictionary format. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "name": ("STRING", {"default": "", "multiline": False}), - "download": ("BOOLEAN", {"default": True}), - "root": ("STRING", {"default": "", "multiline": False}), - "batch_size": ("INT", {"default": 1, "min": 1, "max": 1e6}), - "shuffle": ("BOOLEAN", {"default": False}), - }, - "optional": { - "dataset_parameters": ("STRING", {"default": '{"train":True}', "multiline": True}), - "load_parameters": ("STRING", {"default": '{"num_workers:1}', "multiline": True}) - } - } - - RETURN_TYPES: Tuple[str] = ("PTDATALOADER",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, - name: str, - download: bool, - root: str, - batch_size: int, - shuffle: bool, - dataset_parameters: str, - load_parameters: str) -> Tuple: - """ - Loads a dataset from Torchvision with specified parameters. - - Args: - name (str): Name of the dataset class (e.g., MNIST, FashionMNIST). - download (bool): Whether to download the dataset. - root (str): Root directory for storing the dataset. - batch_size (int): The number of samples per batch. - shuffle (bool): If True, shuffles the dataset before each epoch. - dataset_parameters (str): Additional dataset parameters in stringified dictionary format. - load_parameters (str): Additional parameters for data load in Python dictionary format. - - Returns: - Tuple: A tuple containing the dataset instance. - """ - - with torch.inference_mode(False): - dataset_param_dict = ast.literal_eval(dataset_parameters) - - # Converts the datasets class name to dataset class itself - try: - dataset_class = getattr(datasets, name) - except AttributeError: - raise ValueError(f"Dataset '{name}' is not available in torchvision.datasets") - - # Get valid parameters for the dataset class - valid_params = inspect.signature(dataset_class).parameters - - # Filter only parameters that match the dataset's constructor - filtered_params = {k: v for k, v in dataset_param_dict.items() if k in valid_params} - - if root: - dataset_path = get_dataset_full_path(root) - else: # Use default directory - dataset_path = get_dataset_full_path("") - - transform = transforms.Compose([transforms.ToTensor()]) - dc = dataset_class(download=download, - root=dataset_path, - transform=transform, - **filtered_params) - - - load_param_dict = ast.literal_eval(load_parameters) - - # Get valid parameters for the DataLoader class - valid_params = inspect.signature(DataLoader).parameters - - # Filter only parameters that match the dataset's constructor - filtered_params = {k: v for k, v in load_param_dict.items() if k in valid_params} - - dl = DataLoader(dataset=dc, - batch_size=batch_size, - shuffle=shuffle, - **filtered_params) - return (dl,) \ No newline at end of file diff --git a/modules/pytorch_wrapper/ptv_image_folder_dataset.py b/modules/pytorch_wrapper/ptv_image_folder_dataset.py deleted file mode 100644 index 44ac685..0000000 --- a/modules/pytorch_wrapper/ptv_image_folder_dataset.py +++ /dev/null @@ -1,73 +0,0 @@ -from typing import Any, Dict, Optional, Callable, Tuple -import torch -from torchvision.datasets import ImageFolder - -from .utils import get_dataset_full_path - -class PtvImageFolderDataset: - """ - A Torchvision ImageFolder Dataset class wrapper. - - Parameters - - **root** - Specify the root directory that contains subdirectories which of which contains images for each class. - The subdirectory name needs to be named after each class. - - **transform** - Data transforms e.g. transform to PyTorch tensor, normalize image. - Plug in the PTV Transforms node that contains Torchvision Transforms functionality. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: A dictionary of required input types. - """ - return { - "required": { - "root": ("STRING", {"default": "", "multiline": False}) - }, - "optional": { - "transform": ("PTVTRANSFORM", {}) - } - } - - RETURN_TYPES: Tuple[str] = ("PTVDATASET",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - @classmethod - def IS_CHANGED(cls, **kw): - return float("NaN") - - def f(self, - root: str, - transform: Optional[Callable] = None) -> Tuple: - """ - Loads a dataset from Torchvision with specified parameters. - - Args: - root (str): Root directory for storing the dataset. - transform (Optional[Callable]): Transformations to apply to the dataset. - - Returns: - Tuple: A tuple containing the dataset instance. - """ - - with torch.inference_mode(False): - - if root: - dataset_path = get_dataset_full_path(root) - else: # Use default directory - dataset_path = get_dataset_full_path("") - - dc = ImageFolder(root=dataset_path, - transform=transform - ) - return (dc,) diff --git a/modules/pytorch_wrapper/ptv_transforms_resize.py b/modules/pytorch_wrapper/ptv_transforms_resize.py deleted file mode 100644 index 39b5eb7..0000000 --- a/modules/pytorch_wrapper/ptv_transforms_resize.py +++ /dev/null @@ -1,48 +0,0 @@ -from typing import Any, Dict -import torchvision.transforms as transforms - - -class PtvTransformsResize: - """ - Resizes and transforms elements of dataset to PyTorch tensors. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: An empty dictionary. - """ - return { - "required": { - "height": ("INT", {"default": 256, "min": 1, "max": 32768}), - "width": ("INT", {"default": 256, "min": 1, "max": 32768}) - }, - } - - RETURN_TYPES: tuple = ("PTVTRANSFORM",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - def f(self, height: int, width: int) -> tuple: - """ - Resizes and transforms elements of dataset to PyTorch tensors. - - Args: - height (int): Target height of the input image after transform - width (int): Target width of the inpt image after transform - - Returns: - tuple: A tuple containing the transform callable. - """ - c = transforms.Compose([ - transforms.Resize((height, width)), - transforms.ToTensor() - ]) - return(c,) - - diff --git a/modules/pytorch_wrapper/ptv_transforms_to_tensor.py b/modules/pytorch_wrapper/ptv_transforms_to_tensor.py deleted file mode 100644 index 89fdded..0000000 --- a/modules/pytorch_wrapper/ptv_transforms_to_tensor.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import Any, Dict, Optional, Callable -import torchvision.transforms as transforms - - -class PtvTransformsToTensor: - """ - Transforms elements of dataset to PyTorch tensors. - - category: PyTorch wrapper - Training - """ - - @classmethod - def INPUT_TYPES(cls) -> Dict[str, Any]: - """ - Defines the required input types. - - Returns: - Dict[str, Any]: An empty dictionary. - """ - return { - } - - RETURN_TYPES: tuple = ("PTVTRANSFORM",) - FUNCTION: str = "f" - CATEGORY: str = "Training" - - def f(self) -> tuple: - """ - Transforms elements of dataset to PyTorch tensors. - - Returns: - tuple: A tuple containing the transform callable. - """ - c = transforms.Compose([transforms.ToTensor()]) - return(c,) - - diff --git a/modules/pytorch_wrapper/utils.py b/modules/pytorch_wrapper/utils.py deleted file mode 100644 index f9e9cb6..0000000 --- a/modules/pytorch_wrapper/utils.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import ast -from typing import Optional, Tuple, Union -import torch - -DTYPE_MAPPING = { - "float32": torch.float32, - "float16": torch.float16, - "bfloat16": torch.bfloat16, - "float64": torch.float64, - "uint8": torch.uint8, - "int8": torch.int8, - "int16": torch.int16, - "int32": torch.int32, - "int64": torch.int64, - "bool": torch.bool -} - - -def get_resource_full_path(resource_name: str, resource_path: str) -> str: - """ - Resolves the absolute path to a resource file within the "resources" directory and - ensures that the directory exists. - - Args: - resource_path (str): The path to the resource file. If the path is a relative path, - the path is considered relative to the `resource` directory of this extension. - - Returns: - str: The absolute path to the resource file. - """ - if os.path.isabs(resource_path): - resource_full_path = resource_path - else: - resource_full_path = os.path.realpath( - os.path.join(os.path.dirname(__file__), "..", "..", resource_name, resource_path)) - resource_dir = os.path.dirname(resource_full_path) - if os.path.exists(resource_dir) is False: - os.makedirs(resource_dir) - return resource_full_path - - -def get_model_full_path(model_path: str) -> str: - """ - Resolves the absolute path to a model file within the "models" directory and - ensures that the directory exists. - - Args: - model_path (str): The path to the model file. If the path is a relative path, - the path is considered relative to the `models` directory of this extension. - - Returns: - str: The absolute path to the model file. - """ - return get_resource_full_path("models", model_path) - - -def get_dataset_full_path(dataset_path: str) -> str: - """ - Resolves the absolute path to the datasete within the "datasets" directory and - ensures that the directory exists. - - Args: - dataset_path (str): The path to the dataset file. If the path is a relative path, - the path is considered relative to the `datasets` directory of this extension. - - Returns: - str: The absolute path to the dataset file. - """ - return get_resource_full_path("datasets", dataset_path) - - -def str_to_dim(dim: str) -> Optional[Union[int, Tuple[int, ...]]]: - """ - Converts a string representation of a dimension into an integer or a tuple of integers. - - Args: - dim (str): A string representing an integer or a tuple of integers. - - Returns: - Optional[Union[int, Tuple[int, ...]]]: - - An integer if the input represents a single integer. - - A tuple of integers if the input represents a list or tuple. - - None if the input is empty. - - Raises: - ValueError: If the parsed value is not an integer or a tuple of integers. - """ - if dim: - # Convert string to an integer, list, or tuple of integers - parsed_dim = ast.literal_eval(dim) - - # Convert list to tuple - if isinstance(parsed_dim, list): - parsed_dim = tuple(parsed_dim) - - # Ensure the parsed dim is valid - if not isinstance(parsed_dim, (int, tuple)) or ( - isinstance(parsed_dim, tuple) and not all(isinstance(i, int) for i in parsed_dim) - ): - raise ValueError(f"Invalid format for dim: {parsed_dim}. Must be an integer or a tuple of integers.") - - return parsed_dim - - return None - diff --git a/pyproject.toml b/pyproject.toml index 438106d..e855d93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "data-analysis" description = "Data analysis custom modules for ComfyUI – Integrates Pandas, Seaborn and Matplotlib into ComfyUI, featuring extensive PyTorch wrapper nodes for seamless tensor operations. Experimental PyTorch model training was added in v2.0." -version = "2.0.11" +version = "3.0.3" license = {file = "LICENSE"} [project.urls] diff --git a/tests/pytorch_wrapper/__init__.py b/tests/pytorch_wrapper/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/pytorch_wrapper/pt_abs_test.py b/tests/pytorch_wrapper/pt_abs_test.py deleted file mode 100644 index 046e88a..0000000 --- a/tests/pytorch_wrapper/pt_abs_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_abs import PtAbs # Updated import to PtAbs - - -class TestPtAbs(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtAbs() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([-1, 2, -3, 4], dtype=torch.float32), torch.tensor([1, 2, 3, 4], dtype=torch.float32)), # Mixed positive/negative - (torch.tensor([0, -5, 10, -15], dtype=torch.int32), torch.tensor([0, 5, 10, 15], dtype=torch.int32)), # Integer case - (torch.tensor([[-1.5, 2.3], [-3.7, 4.9]], dtype=torch.float32), torch.tensor([[1.5, 2.3], [3.7, 4.9]], dtype=torch.float32)), # 2D case - (torch.tensor([[-100, 0, 50], [-25, -75, 100]], dtype=torch.int64), torch.tensor([[100, 0, 50], [25, 75, 100]], dtype=torch.int64)), # Large numbers - (torch.full((2, 2), -7.7, dtype=torch.float32), torch.full((2, 2), 7.7, dtype=torch.float32)), # Constant matrix - ] - - def test_absolute_value(self): - """Test tensor element-wise absolute value using torch.abs().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected absolute value operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_acos_test.py b/tests/pytorch_wrapper/pt_acos_test.py deleted file mode 100644 index 528acf8..0000000 --- a/tests/pytorch_wrapper/pt_acos_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_acos import PtAcos # Updated import to PtAcos - - -class TestPtAcos(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtAcos() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32), torch.acos(torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.acos(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.acos(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.acos(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_acos(self): - """Test tensor element-wise arc cosine using torch.acos().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected acos values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_add_test.py b/tests/pytorch_wrapper/pt_add_test.py deleted file mode 100644 index a46d181..0000000 --- a/tests/pytorch_wrapper/pt_add_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_add import PtAdd - - -class TestPtAdd(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtAdd() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 2.0, 3.0]), torch.tensor([4.0, 5.0, 6.0]), torch.tensor([5.0, 7.0, 9.0])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), 2.0)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.ones(2, 2)), - (torch.tensor([[1.0], [2.0]]), torch.tensor([[3.0], [4.0]]), torch.tensor([[4.0], [6.0]])), - ] - - def test_addition(self): - """Test tensor addition.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected sum - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_arange_test.py b/tests/pytorch_wrapper/pt_arange_test.py deleted file mode 100644 index d80f56c..0000000 --- a/tests/pytorch_wrapper/pt_arange_test.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_arange import PtArange - - -class TestPtArange(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtArange() - - # Test cases: (start, end, step, dtype, expected_tensor, expected_dtype) - self.test_cases = [ - ("0", "5", "1", "int32", torch.tensor([0, 1, 2, 3, 4], dtype=torch.int32), torch.int32), # Simple range - ("-3", "3", "1", "float32", torch.tensor([-3, -2, -1, 0, 1, 2], dtype=torch.float32), torch.float32), # Negative start - ("1.5", "4.5", "1", "float64", torch.tensor([1.5, 2.5, 3.5], dtype=torch.float64), torch.float64), # Floating point step - ("10", "0", "-2", "int64", torch.tensor([10, 8, 6, 4, 2], dtype=torch.int64), torch.int64), # Decreasing range - ("", "5", "1", "int8", torch.tensor([0, 1, 2, 3, 4], dtype=torch.int8), torch.int8), # Default start (0) - ("0", "10", "", "uint8", torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=torch.uint8), torch.uint8), # Default step (1) - ] - - def test_arange_tensor_creation(self): - """Test tensor generation using torch.arange(), including values and dtype.""" - for start, end, step, dtype, expected, expected_dtype in self.test_cases: - with self.subTest(start=start, end=end, step=step, dtype=dtype): - result, = self.node.f(start, end, step, dtype) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected tensor values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - # Ensure result has the correct dtype - self.assertEqual(result.dtype, expected_dtype, f"Expected dtype {expected_dtype}, got {result.dtype}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_argmax_test.py b/tests/pytorch_wrapper/pt_argmax_test.py deleted file mode 100644 index 2be354b..0000000 --- a/tests/pytorch_wrapper/pt_argmax_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_argmax import PtArgmax - - -class TestPtArgmax(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtArgmax() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - (torch.tensor([[1, 3, 2], [4, 0, 5]]), "0", False, torch.tensor([1, 0, 1])), - (torch.tensor([[1, 3, 2], [4, 0, 5]]), "1", True, torch.tensor([[1], [2]])), - (torch.tensor([[10, 3, 2], [123, 0, 5]]), "", False, torch.tensor(3)), - ] - - def test_argmax(self): - """Test torch.argmax behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected indices - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_argmin_test.py b/tests/pytorch_wrapper/pt_argmin_test.py deleted file mode 100644 index 89753c9..0000000 --- a/tests/pytorch_wrapper/pt_argmin_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_argmin import PtArgmin - - -class TestPtArgmin(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtArgmin() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - (torch.tensor([[1, 3, 2], [4, 0, 5]]), "0", False, torch.tensor([0, 1, 0])), - (torch.tensor([[1, 3, 2], [4, 0, 5]]), "1", True, torch.tensor([[0], [1]])), - (torch.tensor([[1, 3, 2], [4, 0, 5]]), "", False, torch.tensor(4)), - ] - - def test_argmin(self): - """Test torch.argmin behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected indices - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_asin_test.py b/tests/pytorch_wrapper/pt_asin_test.py deleted file mode 100644 index 92f8905..0000000 --- a/tests/pytorch_wrapper/pt_asin_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_asin import PtAsin # Updated import to PtAsin - - -class TestPtAsin(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtAsin() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32), torch.asin(torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.asin(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.asin(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.asin(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_asin(self): - """Test tensor element-wise arc sine using torch.asin().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected asin values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_atan_test.py b/tests/pytorch_wrapper/pt_atan_test.py deleted file mode 100644 index 551d7a5..0000000 --- a/tests/pytorch_wrapper/pt_atan_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_atan import PtAtan # Updated import to PtAtan - - -class TestPtAtan(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtAtan() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32), torch.atan(torch.tensor([1.0, 0.0, -1.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.atan(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.atan(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.atan(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_atan(self): - """Test tensor element-wise arc tangent using torch.atan().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected atan values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_and_test.py b/tests/pytorch_wrapper/pt_bitwise_and_test.py deleted file mode 100644 index 630d459..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_and_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_and import PtBitwiseAnd # Updated import to PtBitwiseAnd - - -class TestPtBitwiseAnd(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseAnd() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([0b0001, 0b0011, 0b0101]), torch.tensor([0b0001, 0b0010, 0b0110]), torch.tensor([0b0001, 0b0010, 0b0100])), - (torch.tensor([0b1111, 0b1010, 0b1100]), torch.tensor([0b0101, 0b1100, 0b1010]), torch.tensor([0b0101, 0b1000, 0b1000])), - (torch.tensor([1, 2, 3]), torch.tensor([3, 2, 1]), torch.tensor([1, 2, 1])), - (torch.ones(2, 2, dtype=torch.int32), torch.zeros(2, 2, dtype=torch.int32), torch.zeros(2, 2, dtype=torch.int32)), - (torch.full((2, 2), 0b1010, dtype=torch.int32), torch.full((2, 2), 0b1100, dtype=torch.int32), torch.full((2, 2), 0b1000, dtype=torch.int32)), - ] - - def test_bitwise_and(self): - """Test tensor element-wise bitwise AND using torch.bitwise_and().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise AND operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_left_shift_test.py b/tests/pytorch_wrapper/pt_bitwise_left_shift_test.py deleted file mode 100644 index 124b8bf..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_left_shift_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_left_shift import PtBitwiseLeftShift # Updated import to PtBitwiseLeftShift - - -class TestPtBitwiseLeftShift(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseLeftShift() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 4], dtype=torch.int64), torch.tensor([1, 2, 3], dtype=torch.int64), torch.tensor([2, 8, 32], dtype=torch.int64)), # 1<<1, 2<<2, 4<<3 - (torch.tensor([4, 8, 16], dtype=torch.int64), torch.tensor([2, 1, 3], dtype=torch.int64), torch.tensor([16, 16, 128], dtype=torch.int64)), # 4<<2, 8<<1, 16<<3 - (torch.tensor([0b0001, 0b0010, 0b0100], dtype=torch.int64), torch.tensor([1, 2, 3], dtype=torch.int64), torch.tensor([0b0010, 0b1000, 0b100000], dtype=torch.int64)), # Bitwise shift - (torch.ones(3, 3, dtype=torch.int64), torch.full((3, 3), 2, dtype=torch.int64), torch.full((3, 3), 4, dtype=torch.int64)), # 1<<2 = 4 - (torch.full((2, 2), 5, dtype=torch.int64), torch.full((2, 2), 3, dtype=torch.int64), torch.full((2, 2), 40, dtype=torch.int64)), # 5<<3 = 40 - ] - - def test_bitwise_left_shift(self): - """Test tensor element-wise bitwise left shift using torch.bitwise_left_shift().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise left shift operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_not_test.py b/tests/pytorch_wrapper/pt_bitwise_not_test.py deleted file mode 100644 index a7d87d8..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_not_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_not import PtBitwiseNot # Updated import to PtBitwiseNot - - -class TestPtBitwiseNot(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseNot() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0, 1, 2, 3], dtype=torch.int32), torch.tensor([-1, -2, -3, -4], dtype=torch.int32)), # Bitwise NOT - (torch.tensor([0b0000, 0b0001, 0b0010], dtype=torch.int32), torch.tensor([-1, -2, -3], dtype=torch.int32)), # Binary representation - (torch.tensor([[5, 10], [15, 20]], dtype=torch.int32), torch.tensor([[-6, -11], [-16, -21]], dtype=torch.int32)), # Matrix case - (torch.full((2, 2), 0, dtype=torch.int32), torch.full((2, 2), -1, dtype=torch.int32)), # NOT 0 -> -1 - (torch.full((3, 3), -1, dtype=torch.int32), torch.full((3, 3), 0, dtype=torch.int32)), # NOT -1 -> 0 - ] - - def test_bitwise_not(self): - """Test tensor element-wise bitwise NOT using torch.bitwise_not().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise NOT operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_or_test.py b/tests/pytorch_wrapper/pt_bitwise_or_test.py deleted file mode 100644 index 9b606fd..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_or_test.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_or import PtBitwiseOr # Updated import to PtBitwiseOr - - -class TestPtBitwiseOr(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseOr() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([0b0001, 0b0011, 0b0101], dtype=torch.int32), - torch.tensor([0b0010, 0b0100, 0b0110], dtype=torch.int32), - torch.tensor([0b0011, 0b0111, 0b0111], dtype=torch.int32)), # Binary OR - - (torch.tensor([1, 2, 4], dtype=torch.int32), - torch.tensor([8, 16, 32], dtype=torch.int32), - torch.tensor([9, 18, 36], dtype=torch.int32)), # Decimal OR - - (torch.tensor([5, 10, 15], dtype=torch.int32), - torch.tensor([3, 6, 12], dtype=torch.int32), - torch.tensor([7, 14, 15], dtype=torch.int32)), # Mixed values - - (torch.zeros(3, 3, dtype=torch.int32), - torch.ones(3, 3, dtype=torch.int32), - torch.ones(3, 3, dtype=torch.int32)), # OR with all ones - - (torch.full((2, 2), 0b1010, dtype=torch.int32), - torch.full((2, 2), 0b1100, dtype=torch.int32), - torch.full((2, 2), 0b1110, dtype=torch.int32)), # OR with constant matrices - ] - - def test_bitwise_or(self): - """Test tensor element-wise bitwise OR using torch.bitwise_or().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise OR operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_right_shift_test.py b/tests/pytorch_wrapper/pt_bitwise_right_shift_test.py deleted file mode 100644 index 69a9b9b..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_right_shift_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_right_shift import PtBitwiseRightShift # Updated import to PtBitwiseRightShift - - -class TestPtBitwiseRightShift(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseRightShift() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([4, 8, 16], dtype=torch.int64), torch.tensor([1, 2, 3], dtype=torch.int64), torch.tensor([2, 2, 2], dtype=torch.int64)), # 4>>1, 8>>2, 16>>3 - (torch.tensor([32, 64, 128], dtype=torch.int64), torch.tensor([2, 3, 4], dtype=torch.int64), torch.tensor([8, 8, 8], dtype=torch.int64)), # 32>>2, 64>>3, 128>>4 - (torch.tensor([0b1000, 0b10000, 0b100000], dtype=torch.int64), torch.tensor([1, 2, 3], dtype=torch.int64), torch.tensor([0b0100, 0b00100, 0b000100], dtype=torch.int64)), # Bitwise shift - (torch.full((3, 3), 16, dtype=torch.int64), torch.full((3, 3), 2, dtype=torch.int64), torch.full((3, 3), 4, dtype=torch.int64)), # 16>>2 = 4 - (torch.full((2, 2), 40, dtype=torch.int64), torch.full((2, 2), 3, dtype=torch.int64), torch.full((2, 2), 5, dtype=torch.int64)), # 40>>3 = 5 - ] - - def test_bitwise_right_shift(self): - """Test tensor element-wise bitwise right shift using torch.bitwise_right_shift().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise right shift operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bitwise_xor_test.py b/tests/pytorch_wrapper/pt_bitwise_xor_test.py deleted file mode 100644 index 24ce242..0000000 --- a/tests/pytorch_wrapper/pt_bitwise_xor_test.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bitwise_xor import PtBitwiseXor # Updated import to PtBitwiseXor - - -class TestPtBitwiseXor(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBitwiseXor() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([0b0001, 0b0011, 0b0101], dtype=torch.int32), - torch.tensor([0b0010, 0b0100, 0b0110], dtype=torch.int32), - torch.tensor([0b0011, 0b0111, 0b0011], dtype=torch.int32)), # Binary XOR - - (torch.tensor([1, 2, 4], dtype=torch.int32), - torch.tensor([8, 16, 32], dtype=torch.int32), - torch.tensor([9, 18, 36], dtype=torch.int32)), # Decimal XOR - - (torch.tensor([5, 10, 15], dtype=torch.int32), - torch.tensor([3, 6, 12], dtype=torch.int32), - torch.tensor([6, 12, 3], dtype=torch.int32)), # Mixed values - - (torch.zeros(3, 3, dtype=torch.int32), - torch.ones(3, 3, dtype=torch.int32), - torch.ones(3, 3, dtype=torch.int32)), # XOR with all ones - - (torch.full((2, 2), 0b1010, dtype=torch.int32), - torch.full((2, 2), 0b1100, dtype=torch.int32), - torch.full((2, 2), 0b0110, dtype=torch.int32)), # XOR with constant matrices - ] - - def test_bitwise_xor(self): - """Test tensor element-wise bitwise XOR using torch.bitwise_xor().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected bitwise XOR operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bmm_test.py b/tests/pytorch_wrapper/pt_bmm_test.py deleted file mode 100644 index e1e1a87..0000000 --- a/tests/pytorch_wrapper/pt_bmm_test.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bmm import PtBmm # Updated import to PtBmm - - -class TestPtBmm(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtBmm() - - # Valid test cases: (Tensor A, Tensor B, Expected result) - self.valid_test_cases = [ - # Case 1: Batch of 2 matrices (3x4) * (4x5) → (2, 3, 5) - (torch.ones(2, 3, 4), torch.ones(2, 4, 5), torch.full((2, 3, 5), 4.0)), - - # Case 2: Batch of 3 matrices (2x3) * (3x2) → (3, 2, 2) - (torch.tensor([[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]]), - torch.tensor([[[7.0, 8.0], [9.0, 10.0], [11.0, 12.0]]]), - torch.tensor([[[58.0, 64.0], [139.0, 154.0]]])), - - # Case 3: Identity matrix batch multiplication (should remain the same) - (torch.eye(3).expand(4, -1, -1), torch.eye(3).expand(4, -1, -1), torch.eye(3).expand(4, -1, -1)), - ] - - # Invalid test cases (should raise errors) - self.invalid_test_cases = [ - (torch.ones(3, 4), torch.ones(4, 5)), # 2D tensors (not allowed) - (torch.ones(2, 3, 4), torch.ones(3, 4, 5)), # Mismatched batch size - (torch.ones(2, 3, 4, 5), torch.ones(2, 5, 6)), # 4D tensors (not allowed) - (torch.ones(2, 3, 4), torch.ones(2, 5, 6)), # Matmul shape mismatch within batch - ] - - def test_batched_matrix_multiplication(self): - """Test valid batched matrix multiplication cases.""" - for tens_a, tens_b, expected in self.valid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected batch matrix multiplication - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_invalid_multiplication(self): - """Test invalid cases where dimensions do not match.""" - for tens_a, tens_b in self.invalid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - with self.assertRaises(Exception, msg=f"torch.bmm() should fail for shapes {tens_a.shape} and {tens_b.shape}"): - self.node.f(tens_a, tens_b) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_bool_create_test.py b/tests/pytorch_wrapper/pt_bool_create_test.py deleted file mode 100644 index 8e3ce6e..0000000 --- a/tests/pytorch_wrapper/pt_bool_create_test.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_bool_create import PtBoolCreate - -class TestPtBoolCreate(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtBoolCreate() - - # Test cases covering various ranks - self.test_cases = [ - # Rank 0 (scalar) - ("True", torch.tensor(True, dtype=torch.bool)), - ("False", torch.tensor(False, dtype=torch.bool)), - - # Rank 1 (1D array) - ("[True, False, True]", torch.tensor([True, False, True], dtype=torch.bool)), - - # Rank 2 (2D matrix) - ("[[True, False], [False, True]]", torch.tensor([[True, False], [False, True]], dtype=torch.bool)), - - # Rank 3 (3D tensor) - ( - "[[[True, False], [False, True]], [[False, True], [True, False]]]", - torch.tensor([[[True, False], [False, True]], [[False, True], [True, False]]], dtype=torch.bool), - ), - ] - - def test_create_tensor(self): - """Test PyTorch boolean tensor creation from various structured inputs.""" - for data_str, expected_tensor in self.test_cases: - with self.subTest(data=data_str): - retval = self.node.f(data_str)[0] - - # Ensure the returned value is a PyTorch tensor - self.assertTrue(isinstance(retval, torch.Tensor), f"Expected tensor, got {type(retval)}") - - # Ensure the dtype is bool - self.assertEqual(retval.dtype, torch.bool, f"Dtype mismatch for input: {data_str}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_tensor.shape, - f"Shape mismatch for input: {data_str} (Expected {expected_tensor.shape}, got {retval.shape})") - - # Ensure values match - torch.testing.assert_close(retval, expected_tensor, - msg=f"Value mismatch for input: {data_str}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_cos_test.py b/tests/pytorch_wrapper/pt_cos_test.py deleted file mode 100644 index 9d03217..0000000 --- a/tests/pytorch_wrapper/pt_cos_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_cos import PtCos # Updated import to PtCos - - -class TestPtCos(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtCos() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, torch.pi / 2, torch.pi], dtype=torch.float32), torch.cos(torch.tensor([0.0, torch.pi / 2, torch.pi], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.cos(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.cos(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.cos(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_cos(self): - """Test tensor element-wise cosine using torch.cos().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected cos values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_cosh_test.py b/tests/pytorch_wrapper/pt_cosh_test.py deleted file mode 100644 index 299fec0..0000000 --- a/tests/pytorch_wrapper/pt_cosh_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_cosh import PtCosh # Updated import to PtCosh - - -class TestPtCosh(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtCosh() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32), torch.cosh(torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.cosh(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.cosh(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.cosh(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_cosh(self): - """Test tensor element-wise hyperbolic cosine using torch.cosh().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected cosh values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_crop_test.py b/tests/pytorch_wrapper/pt_crop_test.py deleted file mode 100644 index 8ebe074..0000000 --- a/tests/pytorch_wrapper/pt_crop_test.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.pt_crop import PtCrop - - -class TestPtCrop(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtCrop() - - # Test cases: (Input tensor, Height, Width, Expected shape) - self.test_cases = [ - (torch.rand(1, 3, 16, 16), 8, 8, (1, 3, 8, 8)), # Crop 4D tensor - (torch.rand(3, 16, 16), 8, 8, (3, 8, 8)), # Crop 3D tensor - (torch.rand(1, 3, 16, 16), 16, 16, (1, 3, 16, 16)), # No crop, same size - ] - - def test_crop(self): - """Test tensor cropping to specific sizes.""" - for tens, height, width, expected_shape in self.test_cases: - with self.subTest(height=height, width=width): - result, = self.node.f(tens, height, width) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - - def test_invalid_tensor_rank(self): - """Test that an invalid tensor rank raises an error.""" - tens = torch.rand(16, 16) # 2D tensor (invalid) - with self.assertRaises(ValueError, msg="Only rank 3 or 4 tensors are supported for crop."): - self.node.f(tens, 8, 8) - - def test_crop_exceeds_dimensions(self): - """Test that cropping beyond tensor dimensions raises an error.""" - tens = torch.rand(1, 3, 16, 16) - with self.assertRaises(ValueError, msg="Specified crop size exceeds tensor dimensions."): - self.node.f(tens, 32, 32) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_data_loader_test.py b/tests/pytorch_wrapper/pt_data_loader_test.py deleted file mode 100644 index 6b59a75..0000000 --- a/tests/pytorch_wrapper/pt_data_loader_test.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor -from pytorch_wrapper.pt_data_loader import PtDataLoader - -class TestPtDataLoader(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.dataset_node = PtvDataset() - self.compose_node = PtvTransformsToTensor() - self.data_loader_node = PtDataLoader() - - def test_with_transform(self): - """Tests with transform""" - bs = 2 - transform = self.compose_node.f()[0] - dataset = self.dataset_node.f("MNIST", - True, # download - "", # root - '{"train": True}', - transform=transform)[0] - train_data = self.data_loader_node.f( - dataset=dataset, - batch_size=bs, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - x, y = next(iter(train_data)) - self.assertEqual(x.size(), torch.Size([bs, 1, 28, 28])) - self.assertEqual(y.size(), torch.Size([bs])) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_div_test.py b/tests/pytorch_wrapper/pt_div_test.py deleted file mode 100644 index 7e6e022..0000000 --- a/tests/pytorch_wrapper/pt_div_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_div import PtDiv # Updated import to PtDiv - - -class TestPtDiv(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtDiv() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([4.0, 10.0, 18.0]), torch.tensor([2.0, 5.0, 6.0]), torch.tensor([2.0, 2.0, 3.0])), - (torch.ones(3, 3), torch.ones(3, 3), torch.ones(3, 3)), # 1 / 1 = 1 - (torch.full((2, 2), 4.0), torch.full((2, 2), 2.0), torch.full((2, 2), 2.0)), # 4 / 2 = 2 - (torch.tensor([[6.0], [12.0]]), torch.tensor([[3.0], [4.0]]), torch.tensor([[2.0], [3.0]])), # Element-wise division - ] - - def test_division(self): - """Test tensor division.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected quotient - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_einsum_test.py b/tests/pytorch_wrapper/pt_einsum_test.py deleted file mode 100644 index ef93fcb..0000000 --- a/tests/pytorch_wrapper/pt_einsum_test.py +++ /dev/null @@ -1,99 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_einsum import PtEinsum # Updated import to PtEinsum - - -class TestPtEinsum(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtEinsum() - - def test_trace_extraction(self): - """Extract the diagonal (1,2,3,4,5) and sum it up (trace).""" - matrix = torch.tensor([[1, 0, 0, 0, 0], - [0, 2, 0, 0, 0], - [0, 0, 3, 0, 0], - [0, 0, 0, 4, 0], - [0, 0, 0, 0, 5]], dtype=torch.float32) - expected = torch.tensor(15.0) # Sum of diagonal - result, = self.node.f("ii", matrix) # Only requires `tens_a` - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_diagonal_extraction(self): - """Extract diagonal elements (1,2,3,4,5).""" - matrix = torch.tensor([[1, 0, 0, 0, 0], - [0, 2, 0, 0, 0], - [0, 0, 3, 0, 0], - [0, 0, 0, 4, 0], - [0, 0, 0, 0, 5]], dtype=torch.float32) - expected = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32) - result, = self.node.f("ii->i", matrix) # Only requires `tens_a` - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_hadamard_product(self): - """Compute Hadamard product (element-wise multiplication).""" - a = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=torch.float32) - b = torch.tensor([[9, 10, 11, 12], [13, 14, 15, 16]], dtype=torch.float32) - expected = a * b - result, = self.node.f("ij,ij->ij", a, b) - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_matrix_multiplication(self): - """Test standard matrix multiplication.""" - a = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=torch.float32) - b = torch.tensor([[9, 10], [11, 12], [13, 14], [15, 16]], dtype=torch.float32) - expected = torch.mm(a, b) - result, = self.node.f("ij,jk->ik", a, b) - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_3d_tensor_multiplication(self): - """Test matrix multiplication for rank-3 tensors.""" - a = torch.ones(2, 3, 4, dtype=torch.float32) - b = torch.ones(2, 4, 5, dtype=torch.float32) - expected = torch.matmul(a, b) - result, = self.node.f("bij,bjk->bik", a, b) - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_4d_tensor_multiplication(self): - """Test matrix multiplication for rank-4 tensors.""" - a = torch.ones(2, 3, 4, 6, dtype=torch.float32) # (batch, groups, rows, cols) - b = torch.ones(2, 3, 6, 5, dtype=torch.float32) # (batch, groups, cols, out_features) - - expected = torch.matmul(a, b) # Standard 4D matrix multiplication - result, = self.node.f("bijk,bikl->bijl", a, b) # Correct einsum notation - - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_bilinear_transformation(self): - """Test bilinear transformation: a vector, W matrix, and b vector.""" - a = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32) - W = torch.tensor([[6, 7, 8, 9, 10], - [11, 12, 13, 14, 15], - [16, 17, 18, 19, 20], - [21, 22, 23, 24, 25], - [26, 27, 28, 29, 30]], dtype=torch.float32) - b = torch.tensor([31, 32, 33, 34, 35], dtype=torch.float32) - - expected = torch.dot(a, torch.matmul(W, b)) - result, = self.node.f("i,ij,j->", a, W, b) - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_tensor_format_conversion(self): - """Test conversion from (B, C, H, W) format to (B, H, W, C) format.""" - a = torch.randn(2, 3, 64, 64, dtype=torch.float32) # (Batch, Channels, Height, Width) - - expected = a.permute(0, 2, 3, 1) # Convert to (Batch, Height, Width, Channels) - result, = self.node.f("bchw->bhwc", a) # Correct einsum notation for format swap - - self.assertTrue(torch.equal(result, expected), f"Expected {expected.shape}, got {result.shape}") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_eq_test.py b/tests/pytorch_wrapper/pt_eq_test.py deleted file mode 100644 index 0943a8f..0000000 --- a/tests/pytorch_wrapper/pt_eq_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_eq import PtEq # Updated import to PtEq - - -class TestPtEq(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtEq() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([1, 2, 3]), torch.tensor([True, True, True])), - (torch.tensor([1, 2, 3]), torch.tensor([3, 2, 1]), torch.tensor([False, True, False])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), True, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), False, dtype=torch.bool)), - (torch.tensor([[1], [2]]), torch.tensor([[1], [3]]), torch.tensor([[True], [False]])), - ] - - def test_equality(self): - """Test tensor element-wise equality using torch.eq().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected element-wise equality - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test.py b/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test.py deleted file mode 100644 index 78e2509..0000000 --- a/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_conv_model import PtnConvModel -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_evaluate_classification_model import PtEvaluateClassificationModel -from pytorch_wrapper.pt_load_model import PtLoadModel - -class TestPtEvaluate(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - # Transform - compose_node = PtvTransformsToTensor() - transform = compose_node.f()[0] - - # Dataset - dataset_node = PtvDataset() - dataset = dataset_node.f("FashionMNIST", - True, # download - "", # root - '{"train": False}', - transform=transform)[0] - - # Data loader - data_loader_node = PtDataLoader() - self.data_loader = data_loader_node.f( - dataset=dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - # Model - self.model_node = PtnConvModel() - self.model = self.model_node.f( - input_dim="(1, 28, 28)", - penultimate_dim=0, - output_dim=10, - channel_list="[32,64,128,256]", - kernel_size_list="[3,3,3,3]", - padding_list="[1,1,1,1]", - downsample_list="[True,True,True,True]" - )[0] - - # Load weights - self.load_model = PtLoadModel() - epochs = 1 - self.loaded_model = self.load_model.f(self.model, f"fashion_mnist_{epochs}_epochs_conv.pt") - - # Instantiates evaluation node - self.evaluate = PtEvaluateClassificationModel() - - def test_evaluation(self): - """ - Tests evaluation. - - Note that this test requires a trained model file on the file system. - Unit test will fail if you run this for the first time. - Run the unit test for training to generate the weight, and re-run this unit test. - """ - accuracy, precision, recall, f1, num_samples = \ - self.evaluate.f(self.model, self.data_loader, use_gpu=True) - print(f""" - accuracy: {accuracy} - precision: {precision} - recall: {recall} - f1: {f1} - Number of samples: {num_samples} - """) - self.assertTrue(accuracy > 0.8) - self.assertEqual(num_samples, 10000) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test2.py b/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test2.py deleted file mode 100644 index cf6419e..0000000 --- a/tests/pytorch_wrapper/pt_evaluate_classification_conv_model_test2.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_conv_model import PtnConvModel -from pytorch_wrapper.ptv_image_folder_dataset import PtvImageFolderDataset -from pytorch_wrapper.ptv_transforms_resize import PtvTransformsResize -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_evaluate_classification_model import PtEvaluateClassificationModel -from pytorch_wrapper.pt_load_model import PtLoadModel - -class TestPtEvaluate(unittest.TestCase): - - @unittest.skipIf(os.getenv("RUN_SKIPPED_TESTS") != "1", "Skipping unless explicitly enabled") - def setUp(self): - """Set up test instance.""" - # Transform - compose_node = PtvTransformsResize() - transform = compose_node.f(256, 256)[0] - - # Dataset - self.node = PtvImageFolderDataset() - dataset = self.node.f("dog_and_cat/val", - transform=transform)[0] - - # Data loader - data_loader_node = PtDataLoader() - self.data_loader = data_loader_node.f( - dataset=dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - # Model - self.model_node = PtnConvModel() - self.model = self.model_node.f( - input_dim="(3, 256, 256)", - penultimate_dim=0, - output_dim=2, - channel_list="[32,64,128,256,512]", # To 128, 64, 32, 16, 8 - kernel_size_list="[3,3,3,3,3]", - padding_list="[1,1,1,1,1]", - downsample_list="[True,True,True,True,True]" - )[0] - - # Load weights - self.load_model = PtLoadModel() - epochs = 20 - self.loaded_model = self.load_model.f(self.model,f"dog_cat_{epochs}_epochs_conv.pt") - - # Instantiates evaluation node - self.evaluate = PtEvaluateClassificationModel() - - @unittest.skipIf(os.getenv("RUN_SKIPPED_TESTS") != "1", "Skipping unless explicitly enabled") - def test_evaluation(self): - """ - Tests evaluation. - - Note that this test requires a trained model file on the file system. - Unit test will fail if you run this for the first time. - Run the unit test for training to generate the weight, and re-run this unit test. - """ - accuracy, precision, recall, f1, num_samples = \ - self.evaluate.f(self.model, self.data_loader, use_gpu=True) - print(f""" - accuracy: {accuracy} - precision: {precision} - recall: {recall} - f1: {f1} - Number of samples: {num_samples} - """) - self.assertTrue(accuracy > 0.7) - self.assertEqual(num_samples, 300) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_evaluate_classification_model_test.py b/tests/pytorch_wrapper/pt_evaluate_classification_model_test.py deleted file mode 100644 index 262e13a..0000000 --- a/tests/pytorch_wrapper/pt_evaluate_classification_model_test.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_linear_model import PtnLinearModel -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_evaluate_classification_model import PtEvaluateClassificationModel -from pytorch_wrapper.pt_load_model import PtLoadModel - -class TestPtEvaluate(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - # Transform - compose_node = PtvTransformsToTensor() - transform = compose_node.f()[0] - - # Dataset - dataset_node = PtvDataset() - dataset = dataset_node.f("FashionMNIST", - True, # download - "", # root - '{"train": False}', - transform=transform)[0] - - # Data loader - data_loader_node = PtDataLoader() - self.data_loader = data_loader_node.f( - dataset=dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - # Model - self.model_node = PtnLinearModel() - self.model = self.model_node.f( - "784,180,42,10", # input dim for first layer, output dim for each layer - "True,True,True", # bias - 3 # num layers - )[0] - - # Load weights - self.load_model = PtLoadModel() - epochs = 1 - self.loaded_model = self.load_model.f(self.model, f"fashion_mnist_{epochs}_epochs.pt") - - # Instntiates evaluation node - self.evaluate = PtEvaluateClassificationModel() - - def test_evaluation(self): - """ - Tests evaluation. - - Note that this test requires a trained model file on the file system. - Unit test will fail if you run this for the first time. - Run the unit test for training to generate the weight, and re-run this unit test. - """ - accuracy, precision, recall, f1, num_samples = \ - self.evaluate.f(self.model, self.data_loader, use_gpu=True) - print(f""" - accuracy: {accuracy} - precision: {precision} - recall: {recall} - f1: {f1} - Number of samples: {num_samples} - """) - self.assertTrue(accuracy > 0.8) - self.assertEqual(num_samples, 10000) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_exp_test.py b/tests/pytorch_wrapper/pt_exp_test.py deleted file mode 100644 index b88551c..0000000 --- a/tests/pytorch_wrapper/pt_exp_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_exp import PtExp # Updated import to PtExp - - -class TestPtExp(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtExp() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, 1.0, 2.0], dtype=torch.float32), torch.exp(torch.tensor([0.0, 1.0, 2.0], dtype=torch.float32))), # Edge cases - (torch.tensor([-1.0, -2.0, 0.5], dtype=torch.float32), torch.exp(torch.tensor([-1.0, -2.0, 0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.exp(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.exp(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_exp(self): - """Test tensor element-wise exponential function using torch.exp().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected exp values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_flatten_test.py b/tests/pytorch_wrapper/pt_flatten_test.py deleted file mode 100644 index 5a66695..0000000 --- a/tests/pytorch_wrapper/pt_flatten_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_flatten import PtFlatten - - -class TestPtFlatten(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtFlatten() - - # Test cases: (Input tensor, Expected flattened tensor shape) - self.test_cases = [ - (torch.randn(3, 4, 5), (60,)), # 3D Tensor - (torch.randn(2, 3, 4, 5), (120,)), # 4D Tensor - (torch.randn(10, 10), (100,)), # 2D Tensor - (torch.randn(1), (1,)), # 1D Tensor remains unchanged - ] - - def test_flatten(self): - """Test flattening tensors correctly.""" - for tensor, expected_shape in self.test_cases: - with self.subTest(tensor_shape=tensor.shape): - flattened, = self.node.f(tensor) - - # Ensure return value is a tensor - self.assertTrue(isinstance(flattened, torch.Tensor), "Output is not a tensor") - - # Ensure shape matches expected flattened shape - self.assertEqual(flattened.shape, expected_shape, f"Shape mismatch: expected {expected_shape}, got {flattened.shape}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_float_create_test.py b/tests/pytorch_wrapper/pt_float_create_test.py deleted file mode 100644 index f5acb08..0000000 --- a/tests/pytorch_wrapper/pt_float_create_test.py +++ /dev/null @@ -1,65 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_float_create import PtFloatCreate - -class TestPtFloatCreate(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtFloatCreate() - - # Test cases covering rank 0 (scalar) to rank 5 tensors - self.test_cases = [ - # Rank 0 (scalar) - ("12345", torch.tensor(12345, dtype=torch.float32)), - ("12345.6", torch.tensor(12345.6, dtype=torch.float32)), - - # Rank 1 (1D array) - ("[1, 2, 3]", torch.tensor([1, 2, 3], dtype=torch.float32)), - ("[1.1, 2.2, 3.3]", torch.tensor([1.1, 2.2, 3.3], dtype=torch.float32)), - - # Rank 2 (2D matrix) - ("[[1, 2, 3], [4, 5, 6]]", torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)), - ("[[1.1, 2.2], [3.3, 4.4]]", torch.tensor([[1.1, 2.2], [3.3, 4.4]], dtype=torch.float32)), - - # Rank 3 (3D tensor) - ("[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]", - torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.float32)), - - # Rank 4 (4D tensor) - ("[[[[1, 2], [3, 4]]], [[[5, 6], [7, 8]]]]", - torch.tensor([[[[1, 2], [3, 4]]], [[[5, 6], [7, 8]]]], dtype=torch.float32)), - - # Rank 5 (5D tensor) - ("[[[[[1], [2]], [[3], [4]]]], [[[[5], [6]], [[7], [8]]]]]", - torch.tensor([[[[[1], [2]], [[3], [4]]]], [[[[5], [6]], [[7], [8]]]]], dtype=torch.float32)), - ] - - def test_create_tensor(self): - """Test PyTorch tensor creation from various structured inputs.""" - for data_str, expected_tensor in self.test_cases: - with self.subTest(data=data_str): - retval = self.node.f(data_str)[0] - - # Ensure the returned value is a PyTorch tensor - self.assertTrue(isinstance(retval, torch.Tensor), f"Expected tensor, got {type(retval)}") - - # Ensure the dtype is float32 - self.assertEqual(retval.dtype, torch.float32, f"Dtype mismatch for input: {data_str}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_tensor.shape, - f"Shape mismatch for input: {data_str} (Expected {expected_tensor.shape}, got {retval.shape})") - - # Ensure values match - torch.testing.assert_close(retval, expected_tensor, - msg=f"Value mismatch for input: {data_str}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_floor_divide_test.py b/tests/pytorch_wrapper/pt_floor_divide_test.py deleted file mode 100644 index 9347727..0000000 --- a/tests/pytorch_wrapper/pt_floor_divide_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_floor_divide import PtFloorDiv - - -class TestPtFloorDiv(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtFloorDiv() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([4.0, 10.0, 18.0]), torch.tensor([3.0, 4.0, 5.0]), torch.tensor([1.0, 2.0, 3.0])), - (torch.ones(3, 3) * 7, torch.ones(3, 3) * 3, torch.ones(3, 3) * 2), # 7 // 3 = 2 - (torch.full((2, 2), 9.0), torch.full((2, 2), 2.0), torch.full((2, 2), 4.0)), # 9 // 2 = 4 - (torch.tensor([[7.0], [15.0]]), torch.tensor([[2.0], [4.0]]), torch.tensor([[3.0], [3.0]])), # Element-wise floor division - ] - - def test_floor_division(self): - """Test tensor floor division.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected floor quotient - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_from_image_transpose_test.py b/tests/pytorch_wrapper/pt_from_image_transpose_test.py deleted file mode 100644 index 6a2b74a..0000000 --- a/tests/pytorch_wrapper/pt_from_image_transpose_test.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_from_image_transpose import PtFromImageTranspose - - -class TestPtFromImageTranspose(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtFromImageTranspose() - - # Define test cases: (input_tensor, expected_shape) - self.test_cases = [ - # Case 1: 3D tensor (H, W, C) -> (C, H, W) - (torch.ones(64, 128, 3), (3, 64, 128)), # (64,128,3) -> (3,64,128) - - # Case 2: 4D tensor (N, H, W, C) -> (N, C, H, W) - (torch.ones(10, 64, 128, 3), (10, 3, 64, 128)), # (10,64,128,3) -> (10,3,64,128) - - # Case 3: Invalid input (2D tensor) - (torch.ones(64, 128), ValueError), # 2D tensors should raise an error - - # Case 4: Invalid input (5D tensor) - (torch.ones(10, 64, 128, 3, 2), ValueError), # 5D tensors should raise an error - ] - - def test_transpose(self): - """Test image transposition operation with valid and invalid cases.""" - for input_tensor, expected in self.test_cases: - with self.subTest(input_shape=input_tensor.shape): - if isinstance(expected, tuple): - # Valid cases - result, = self.node.f(input_tensor) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected), f"Expected shape {expected}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after transpose operation") - else: - # Invalid cases should raise an error - with self.assertRaises(expected): - self.node.f(input_tensor) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_from_numpy_test.py b/tests/pytorch_wrapper/pt_from_numpy_test.py deleted file mode 100644 index 49e6642..0000000 --- a/tests/pytorch_wrapper/pt_from_numpy_test.py +++ /dev/null @@ -1,65 +0,0 @@ -import os -import sys -import unittest -import torch -import numpy as np - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_from_numpy import PtFromNumpy - - -class TestPtFromNumpy(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtFromNumpy() - - # Test cases covering rank 0 (scalar) to rank 3 tensors - self.test_cases = [ - # Rank 0 (scalar) int32 - (np.array(12345, dtype=np.int32), torch.tensor(12345, dtype=torch.int32)), - # Rank 0 (scalar) float32 - (np.array(12345.6, dtype=np.float32), torch.tensor(12345.6, dtype=torch.float32)), - - # Rank 1 (1D array) int32 - (np.array([1, 2, 3], dtype=np.int32), torch.tensor([1, 2, 3], dtype=torch.int32)), - # Rank 1 (1D array) float32 - (np.array([1.1, 2.2, 3.3], dtype=np.float32), torch.tensor([1.1, 2.2, 3.3], dtype=torch.float32)), - - # Rank 2 (2D matrix) int32 - (np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32), torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.int32)), - # Rank 2 (2D matrix) float32 - (np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.float32), torch.tensor([[1.1, 2.2], [3.3, 4.4]], dtype=torch.float32)), - - # Rank 3 (3D tensor) int32 - (np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=np.int32), - torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.int32)), - # Rank 3 (3D tensor) float32 - (np.array([[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]]], dtype=np.float32), - torch.tensor([[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]]], dtype=torch.float32)), - ] - - def test_convert_numpy_to_tensor(self): - """Test conversion of NumPy ndarray to PyTorch tensor.""" - for np_array, expected_tensor in self.test_cases: - with self.subTest(data=np_array): - retval = self.node.f(np_array)[0] - - # Ensure the returned value is a PyTorch tensor - self.assertTrue(isinstance(retval, torch.Tensor), f"Expected tensor, got {type(retval)}") - - # Ensure the dtype matches - self.assertEqual(retval.dtype, expected_tensor.dtype, f"Dtype mismatch for input: {np_array}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_tensor.shape, - f"Shape mismatch for input: {np_array} (Expected {expected_tensor.shape}, got {retval.shape})") - - # Ensure values match - torch.testing.assert_close(retval, expected_tensor, - msg=f"Value mismatch for input: {np_array}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_full_test.py b/tests/pytorch_wrapper/pt_full_test.py deleted file mode 100644 index 77f35de..0000000 --- a/tests/pytorch_wrapper/pt_full_test.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_full import PtFull -from pytorch_wrapper.utils import DTYPE_MAPPING - - -class TestPtFull(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtFull() - - # Tensor size to test - self.size_str = "[2, 3]" # Using a small 2D tensor size for all tests - self.expected_shape = (2, 3) - - # Values to test (using representative values for each type) - self.test_values = { - "float32": "1.5", - "float16": "-2.3", - "bfloat16": "3.7", - "float64": "4.9", - "uint8": "255", # Max value for uint8 - "int8": "-128", # Min value for int8 - "int16": "32767", # Max value for int16 - "int32": "-2147483648", # Min value for int32 - "int64": "9223372036854775807", # Max value for int64 - "bool": "True" - } - - def test_full_tensor_all_dtypes(self): - """Test tensor creation with a specified value for all supported data types.""" - for data_type, torch_dtype in DTYPE_MAPPING.items(): - value_str = self.test_values[data_type] - - with self.subTest(data_type=data_type, value=value_str): - result, = self.node.f(value_str, self.size_str, data_type) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(self.expected_shape), f"Expected shape {self.expected_shape}, got {result.shape}") - - # Ensure result has correct dtype - self.assertEqual(result.dtype, torch_dtype, f"Expected dtype {torch_dtype}, got {result.dtype}") - - # Convert value_str to correct type - if torch_dtype in {torch.float32, torch.float16, torch.bfloat16, torch.float64}: - expected_value = float(value_str) - elif torch_dtype in {torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64}: - expected_value = int(value_str) - elif torch_dtype == torch.bool: - expected_value = value_str.lower() == "true" - else: - raise ValueError(f"Unsupported data type: {data_type}") - - # Ensure all elements match the expected value - expected = torch.full(self.expected_shape, expected_value, dtype=torch_dtype) - self.assertTrue(torch.equal(result, expected), f"Tensor values do not match expected tensor for dtype {data_type}") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_gather_test.py b/tests/pytorch_wrapper/pt_gather_test.py deleted file mode 100644 index df09c79..0000000 --- a/tests/pytorch_wrapper/pt_gather_test.py +++ /dev/null @@ -1,48 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_gather import PtGather - - -class TestPtGather(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtGather() - - # Test cases: (Tensor, Dim, Index (as string), Expected result) - self.test_cases = [ - ( - torch.tensor([[10, 20, 30, 40, 50], [100, 200, 300, 400, 500]]), - 1, - "[[0, 4, 3, 2, 0], [4, 3, 0, 0, 0]]", - torch.tensor([[10, 50, 40, 30, 10], [500, 400, 100, 100, 100]]) - ), - ( - torch.tensor([[1, 2], [3, 4]]), - 0, - "[[1, 0], [0, 1]]", - torch.tensor([[3, 2], [1, 4]]) - ), - ] - - def test_gather(self): - """Test torch.gather behavior.""" - for tens, dim, index, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, index=index): - result, = self.node.f(tens, dim, index) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected gathered values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_ge_test.py b/tests/pytorch_wrapper/pt_ge_test.py deleted file mode 100644 index 92ab581..0000000 --- a/tests/pytorch_wrapper/pt_ge_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_ge import PtGe # Updated import to PtGe - - -class TestPtGe(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtGe() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([0, 2, 4]), torch.tensor([True, True, False])), - (torch.tensor([3, 5, 7]), torch.tensor([1, 5, 10]), torch.tensor([True, True, False])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), True, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), False, dtype=torch.bool)), - (torch.tensor([[5], [10]]), torch.tensor([[5], [10]]), torch.tensor([[True], [True]])), - ] - - def test_greater_or_equal(self): - """Test tensor element-wise greater-than-or-equal condition using torch.ge().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected greater-than-or-equal comparison - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_gt_test.py b/tests/pytorch_wrapper/pt_gt_test.py deleted file mode 100644 index 29603bf..0000000 --- a/tests/pytorch_wrapper/pt_gt_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_gt import PtGt # Updated import to PtGt - - -class TestPtGt(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtGt() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([0, 2, 4]), torch.tensor([True, False, False])), - (torch.tensor([3, 5, 7]), torch.tensor([1, 5, 10]), torch.tensor([True, False, False])), - (torch.ones(3, 3), torch.zeros(3, 3), torch.full((3, 3), True, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), False, dtype=torch.bool)), - (torch.tensor([[5], [10]]), torch.tensor([[3], [10]]), torch.tensor([[True], [False]])), - ] - - def test_greater_than(self): - """Test tensor element-wise greater-than condition using torch.gt().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected greater-than comparison - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_index_select_test.py b/tests/pytorch_wrapper/pt_index_select_test.py deleted file mode 100644 index 8751214..0000000 --- a/tests/pytorch_wrapper/pt_index_select_test.py +++ /dev/null @@ -1,48 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_index_select import PtIndexSelect - - -class TestPtIndexSelect(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtIndexSelect() - - # Test cases: (Tensor, Dim, Index (as string), Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 2, 3], [40, 50, 60], [700, 800, 900]]), - 0, - "[0, 2]", - torch.tensor([[1, 2, 3], [700, 800, 900]]) - ), - ( - torch.tensor([[1, 2, 3], [40, 50, 60], [700, 800, 900]]), - 1, - "[1, 2]", - torch.tensor([[2, 3], [50, 60], [800, 900]]) - ), - ] - - def test_index_select(self): - """Test torch.index_select behavior.""" - for tens, dim, index, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, index=index): - result, = self.node.f(tens, dim, index) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected selected values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_int_create_test.py b/tests/pytorch_wrapper/pt_int_create_test.py deleted file mode 100644 index d77df2e..0000000 --- a/tests/pytorch_wrapper/pt_int_create_test.py +++ /dev/null @@ -1,62 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_int_create import PtIntCreate - -class TestPtIntCreate(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtIntCreate() - - # Test cases covering rank 0 (scalar) to rank 5 tensors - self.test_cases = [ - # Rank 0 (scalar) - ("12345", torch.tensor(12345, dtype=torch.int32)), - - # Rank 1 (1D array) - ("[1, 2, 3]", torch.tensor([1, 2, 3], dtype=torch.int32)), - - # Rank 2 (2D matrix) - ("[[1, 2, 3], [4, 5, 6]]", torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.int32)), - - # Rank 3 (3D tensor) - ("[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]", - torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.int32)), - - # Rank 4 (4D tensor) - ("[[[[1, 2], [3, 4]]], [[[5, 6], [7, 8]]]]", - torch.tensor([[[[1, 2], [3, 4]]], [[[5, 6], [7, 8]]]], dtype=torch.int32)), - - # Rank 5 (5D tensor) - ("[[[[[1], [2]], [[3], [4]]]], [[[[5], [6]], [[7], [8]]]]]", - torch.tensor([[[[[1], [2]], [[3], [4]]]], [[[[5], [6]], [[7], [8]]]]], dtype=torch.int32)), - ] - - def test_create_tensor(self): - """Test PyTorch tensor creation from various structured inputs.""" - for data_str, expected_tensor in self.test_cases: - with self.subTest(data=data_str): - retval = self.node.f(data_str)[0] - - # Ensure the returned value is a PyTorch tensor - self.assertTrue(isinstance(retval, torch.Tensor), f"Expected tensor, got {type(retval)}") - - # Ensure the dtype is int32 - self.assertEqual(retval.dtype, torch.int32, f"Dtype mismatch for input: {data_str}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_tensor.shape, - f"Shape mismatch for input: {data_str} (Expected {expected_tensor.shape}, got {retval.shape})") - - # Ensure values match - torch.testing.assert_close(retval, expected_tensor, - msg=f"Value mismatch for input: {data_str}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_interpolate_by_scale_factor_test.py b/tests/pytorch_wrapper/pt_interpolate_by_scale_factor_test.py deleted file mode 100644 index 07422d0..0000000 --- a/tests/pytorch_wrapper/pt_interpolate_by_scale_factor_test.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_interpolate_by_scale_factor import PtInterpolateByScaleFactor - - -class TestPtInterpolateByScaleFactor(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtInterpolateByScaleFactor() - - # Test cases 3d: (Input tensor, Scale factor, Mode, Expected shape) - self.test_cases_3d = [ - (torch.rand(3, 16, 16), 2.0, "nearest", (3, 32, 32)), - (torch.rand(3, 16, 16), 2.0, "nearest-exact", (3, 32, 32)), - (torch.rand(3, 16, 16), 0.5, "bilinear", (3, 8, 8)), - (torch.rand(3, 16, 16), 1.5, "bicubic", (3, 24, 24)), - ] - - # Test cases: (Input tensor, Scale factor, Mode, Expected shape) - self.test_cases_4d = [ - (torch.rand(1, 3, 16, 16), 2.0, "nearest", (1, 3, 32, 32)), # Upscale 4D tensor - (torch.rand(1, 3, 16, 16), 2.0, "nearest-exact", (1, 3, 32, 32)), # Upscale 4D tensor - (torch.rand(1, 3, 16, 16), 0.5, "bilinear", (1, 3, 8, 8)), # Downscale 4D tensor - (torch.rand(1, 3, 16, 16), 1.5, "bicubic", (1, 3, 24, 24)), # Bicubic mode with 4D tensor - ] - - def test_interpolation_3d(self): - """Test tensor interpolation with different scale factors and modes.""" - for tens, scale_factor, mode, expected_shape in self.test_cases_3d: - with self.subTest(scale_factor=scale_factor, mode=mode): - result, = self.node.f(tens, scale_factor, mode) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - - - def test_interpolation_4d(self): - """Test tensor interpolation with different scale factors and modes.""" - for tens, scale_factor, mode, expected_shape in self.test_cases_4d: - with self.subTest(scale_factor=scale_factor, mode=mode): - result, = self.node.f(tens, scale_factor, mode) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_interpolate_to_size_test.py b/tests/pytorch_wrapper/pt_interpolate_to_size_test.py deleted file mode 100644 index 36baf26..0000000 --- a/tests/pytorch_wrapper/pt_interpolate_to_size_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_interpolate_to_size import PtInterpolateToSize - - -class TestPtInterpolateToSize(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtInterpolateToSize() - - # Test cases 3d: (Input tensor, Height, Width, Mode, Expected shape) - self.test_cases_3d = [ - (torch.rand(3, 16, 16), 32, 32, "nearest", (3, 32, 32)), # Upscale 3D tensor - (torch.rand(3, 16, 16), 32, 32, "nearest-exact", (3, 32, 32)), # Upscale 3D tensor - (torch.rand(3, 16, 16), 8, 8, "bilinear", (3, 8, 8)), # Downscale 3D tensor - (torch.rand(3, 16, 16), 24, 24, "bicubic", (3, 24, 24)), # Bicubic mode with 3D tensor - ] - - # Test cases 4d: (Input tensor, Height, Width, Mode, Expected shape) - self.test_cases_4d = [ - (torch.rand(1, 3, 16, 16), 32, 32, "nearest", (1, 3, 32, 32)), # Upscale 4D tensor - (torch.rand(1, 3, 16, 16), 32, 32, "nearest-exact", (1, 3, 32, 32)), # Upscale 4D tensor - (torch.rand(1, 3, 16, 16), 8, 8, "bilinear", (1, 3, 8, 8)), # Downscale 4D tensor - (torch.rand(1, 3, 16, 16), 24, 24, "bicubic", (1, 3, 24, 24)), # Bicubic mode with 4D tensor - ] - - def test_interpolation_3d(self): - """Test tensor interpolation with different target sizes and modes.""" - for tens, height, width, mode, expected_shape in self.test_cases_3d: - with self.subTest(height=height, width=width, mode=mode): - result, = self.node.f(tens, height, width, mode) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - - - def test_interpolation_4d(self): - """Test tensor interpolation with different target sizes and modes.""" - for tens, height, width, mode, expected_shape in self.test_cases_4d: - with self.subTest(height=height, width=width, mode=mode): - result, = self.node.f(tens, height, width, mode) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_le_test.py b/tests/pytorch_wrapper/pt_le_test.py deleted file mode 100644 index 4cb062d..0000000 --- a/tests/pytorch_wrapper/pt_le_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_le import PtLe # Updated import to PtLe - - -class TestPtLe(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLe() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([0, 2, 4]), torch.tensor([False, True, True])), - (torch.tensor([3, 5, 7]), torch.tensor([1, 5, 10]), torch.tensor([False, True, True])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), True, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), True, dtype=torch.bool)), - (torch.tensor([[5], [10]]), torch.tensor([[5], [10]]), torch.tensor([[True], [True]])), - ] - - def test_less_or_equal(self): - """Test tensor element-wise less-than-or-equal condition using torch.le().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected less-than-or-equal comparison - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_linspace_test.py b/tests/pytorch_wrapper/pt_linspace_test.py deleted file mode 100644 index 3678a1f..0000000 --- a/tests/pytorch_wrapper/pt_linspace_test.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_linspace import PtLinspace - - -class TestPtLinspace(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLinspace() - - # Test cases: (start, end, steps, dtype, expected_tensor, expected_dtype) - self.test_cases = [ - ("0", "10", "5", "float32", torch.tensor([0, 2.5, 5, 7.5, 10], dtype=torch.float32), torch.float32), # Basic float32 case - ("-5", "5", "6", "float64", torch.tensor([-5, -3, -1, 1, 3, 5], dtype=torch.float64), torch.float64), # Negative to positive - ("1", "2", "3", "float16", torch.tensor([1, 1.5, 2], dtype=torch.float16), torch.float16), # Small float16 case - ("100", "200", "5", "int32", torch.tensor([100, 125, 150, 175, 200], dtype=torch.int32), torch.int32), # Large int32 case - ("0", "1", "2", "bfloat16", torch.tensor([0, 1], dtype=torch.bfloat16), torch.bfloat16), # Simple two-step bfloat16 - ] - - def test_linspace_tensor_creation(self): - """Test tensor generation using torch.linspace(), including values and dtype.""" - for start, end, steps, dtype, expected, expected_dtype in self.test_cases: - with self.subTest(start=start, end=end, steps=steps, dtype=dtype): - result, = self.node.f(start, end, steps, dtype) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected tensor values - self.assertTrue(torch.allclose(result, expected, atol=1e-5), f"Expected {expected}, got {result}") - - # Ensure result has the correct dtype - self.assertEqual(result.dtype, expected_dtype, f"Expected dtype {expected_dtype}, got {result.dtype}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_log_test.py b/tests/pytorch_wrapper/pt_log_test.py deleted file mode 100644 index a2b644a..0000000 --- a/tests/pytorch_wrapper/pt_log_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_log import PtLog # Updated import to PtLog - - -class TestPtLog(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLog() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1.0, torch.e, 10.0], dtype=torch.float32), torch.log(torch.tensor([1.0, torch.e, 10.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, 2.0, 3.0], dtype=torch.float32), torch.log(torch.tensor([0.5, 2.0, 3.0], dtype=torch.float32))), # Common values - (torch.tensor([[1.5, 3.2], [4.7, 5.9]], dtype=torch.float32), torch.log(torch.tensor([[1.5, 3.2], [4.7, 5.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 2.5, dtype=torch.float32), torch.log(torch.full((2, 2), 2.5, dtype=torch.float32))), # Constant matrix - ] - - def test_log(self): - """Test tensor element-wise natural logarithm using torch.log().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected log values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_logical_and_test.py b/tests/pytorch_wrapper/pt_logical_and_test.py deleted file mode 100644 index c5227fb..0000000 --- a/tests/pytorch_wrapper/pt_logical_and_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_logical_and import PtLogicalAnd # Updated import to PtLogicalAnd - - -class TestPtLogicalAnd(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLogicalAnd() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([True, False, True]), torch.tensor([False, False, True]), torch.tensor([False, False, True])), - (torch.tensor([[True, True], [False, False]]), torch.tensor([[True, False], [True, False]]), torch.tensor([[True, False], [False, False]])), - (torch.ones(3, 3, dtype=torch.bool), torch.zeros(3, 3, dtype=torch.bool), torch.zeros(3, 3, dtype=torch.bool)), # All true AND all false -> all false - (torch.ones(2, 2, dtype=torch.bool), torch.ones(2, 2, dtype=torch.bool), torch.ones(2, 2, dtype=torch.bool)), # All true AND all true -> all true - (torch.tensor([1, 0, 1, 0], dtype=torch.bool), torch.tensor([1, 1, 0, 0], dtype=torch.bool), torch.tensor([True, False, False, False])), # Mixed cases - ] - - def test_logical_and(self): - """Test tensor element-wise logical AND using torch.logical_and().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected logical AND operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_logical_not_test.py b/tests/pytorch_wrapper/pt_logical_not_test.py deleted file mode 100644 index de18c94..0000000 --- a/tests/pytorch_wrapper/pt_logical_not_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_logical_not import PtLogicalNot # Updated import to PtLogicalNot - - -class TestPtLogicalNot(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLogicalNot() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([True, False, True]), torch.tensor([False, True, False])), - (torch.tensor([[True, True], [False, False]]), torch.tensor([[False, False], [True, True]])), - (torch.ones(3, 3, dtype=torch.bool), torch.zeros(3, 3, dtype=torch.bool)), # NOT all true -> all false - (torch.zeros(2, 2, dtype=torch.bool), torch.ones(2, 2, dtype=torch.bool)), # NOT all false -> all true - (torch.tensor([1, 0, 1, 0], dtype=torch.bool), torch.tensor([False, True, False, True])), # Mixed cases - ] - - def test_logical_not(self): - """Test tensor element-wise logical NOT using torch.logical_not().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected logical NOT operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_logical_or_test.py b/tests/pytorch_wrapper/pt_logical_or_test.py deleted file mode 100644 index 97ae602..0000000 --- a/tests/pytorch_wrapper/pt_logical_or_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_logical_or import PtLogicalOr # Updated import to PtLogicalOr - - -class TestPtLogicalOr(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLogicalOr() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([True, False, True]), torch.tensor([False, False, True]), torch.tensor([True, False, True])), - (torch.tensor([[True, True], [False, False]]), torch.tensor([[False, True], [True, False]]), torch.tensor([[True, True], [True, False]])), - (torch.ones(3, 3, dtype=torch.bool), torch.zeros(3, 3, dtype=torch.bool), torch.ones(3, 3, dtype=torch.bool)), # All true OR all false -> all true - (torch.zeros(2, 2, dtype=torch.bool), torch.zeros(2, 2, dtype=torch.bool), torch.zeros(2, 2, dtype=torch.bool)), # All false OR all false -> all false - (torch.tensor([1, 0, 1, 0], dtype=torch.bool), torch.tensor([1, 1, 0, 0], dtype=torch.bool), torch.tensor([True, True, True, False])), # Mixed cases - ] - - def test_logical_or(self): - """Test tensor element-wise logical OR using torch.logical_or().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected logical OR operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_logical_xor_test.py b/tests/pytorch_wrapper/pt_logical_xor_test.py deleted file mode 100644 index 7756330..0000000 --- a/tests/pytorch_wrapper/pt_logical_xor_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_logical_xor import PtLogicalXor # Updated import to PtLogicalXor - - -class TestPtLogicalXor(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLogicalXor() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([True, False, True]), torch.tensor([False, False, True]), torch.tensor([True, False, False])), - (torch.tensor([[True, True], [False, False]]), torch.tensor([[False, True], [True, False]]), torch.tensor([[True, False], [True, False]])), - (torch.ones(3, 3, dtype=torch.bool), torch.zeros(3, 3, dtype=torch.bool), torch.ones(3, 3, dtype=torch.bool)), # True XOR False -> True - (torch.zeros(2, 2, dtype=torch.bool), torch.zeros(2, 2, dtype=torch.bool), torch.zeros(2, 2, dtype=torch.bool)), # False XOR False -> False - (torch.tensor([1, 0, 1, 0], dtype=torch.bool), torch.tensor([1, 1, 0, 0], dtype=torch.bool), torch.tensor([False, True, True, False])), # Mixed cases - ] - - def test_logical_xor(self): - """Test tensor element-wise logical XOR using torch.logical_xor().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected logical XOR operation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_lt_test.py b/tests/pytorch_wrapper/pt_lt_test.py deleted file mode 100644 index 027c478..0000000 --- a/tests/pytorch_wrapper/pt_lt_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_lt import PtLt # Updated import to PtLt - - -class TestPtLt(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtLt() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([0, 2, 4]), torch.tensor([False, False, True])), - (torch.tensor([3, 5, 7]), torch.tensor([1, 5, 10]), torch.tensor([False, False, True])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), False, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), True, dtype=torch.bool)), - (torch.tensor([[5], [10]]), torch.tensor([[5], [10]]), torch.tensor([[False], [False]])), - ] - - def test_less_than(self): - """Test tensor element-wise less-than condition using torch.lt().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected less-than comparison - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_masked_select_test.py b/tests/pytorch_wrapper/pt_masked_select_test.py deleted file mode 100644 index 7ff2303..0000000 --- a/tests/pytorch_wrapper/pt_masked_select_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_masked_select import PtMaskedSelect - - -class TestPtMaskedSelect(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMaskedSelect() - - # Test cases: (Tensor, Masked Tensor, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 2, 3], [40, 50, 60], [700, 800, 900]]), - torch.tensor([[True, False, False], [False, True, False], [False, False, True]]), - torch.tensor([1, 50, 900]) - ), - ] - - def test_masked_select(self): - """Test torch.masked_select behavior.""" - for tens, masked_tens, expected in self.test_cases: - with self.subTest(tens=tens, masked_tens=masked_tens): - result, = self.node.f(tens, masked_tens) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected selected values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_matmul_test.py b/tests/pytorch_wrapper/pt_matmul_test.py deleted file mode 100644 index d3f5245..0000000 --- a/tests/pytorch_wrapper/pt_matmul_test.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_matmul import PtMatMul # Updated import to PtMatMul - - -class TestPtMatMul(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMatMul() - - # Valid test cases: (Tensor A, Tensor B, Expected result) - self.valid_test_cases = [ - # Case 1: 1D x 1D (dot product) - (torch.tensor([1.0, 2.0, 3.0]), torch.tensor([4.0, 5.0, 6.0]), torch.tensor(32.0)), - - # Case 2: 1D x 2D (vector-matrix multiplication) - (torch.tensor([1.0, 2.0]), torch.tensor([[3.0, 4.0], [5.0, 6.0]]), torch.tensor([13.0, 16.0])), - - # Case 3: 2D x 2D (matrix-matrix multiplication) - (torch.tensor([[1.0, 2.0], [3.0, 4.0]]), torch.tensor([[5.0, 6.0], [7.0, 8.0]]), torch.tensor([[19.0, 22.0], [43.0, 50.0]])), - - # Case 4: 3D x 2D (batched matrix-matrix multiplication) - (torch.ones(2, 3, 4), torch.ones(4, 5), torch.full((2, 3, 5), 4.0)), # (2,3,4) * (4,5) → (2,3,5) - - # Case 5: 3D x 3D (batched matrix multiplication with broadcasting) - (torch.ones(2, 3, 4), torch.ones(2, 4, 5), torch.full((2, 3, 5), 4.0)), # (2,3,4) * (2,4,5) → (2,3,5) - ] - - # Invalid test cases (should raise errors) - self.invalid_test_cases = [ - (torch.ones(2, 3), torch.ones(4, 2)), # (2,3) * (4,2) is invalid - (torch.tensor([1.0, 2.0, 3.0]), torch.tensor([4.0, 5.0])), # Vector size mismatch - (torch.ones(2, 3, 4), torch.ones(3, 5)), # (2,3,4) * (3,5) should fail due to misalignment - ] - - def test_matrix_multiplication(self): - """Test valid matrix multiplication cases.""" - for tens_a, tens_b, expected in self.valid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected matrix multiplication - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_invalid_multiplication(self): - """Test invalid cases where dimensions do not match.""" - for tens_a, tens_b in self.invalid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - with self.assertRaises(RuntimeError, msg=f"MatMul should fail for shapes {tens_a.shape} and {tens_b.shape}"): - self.node.f(tens_a, tens_b) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_max_test.py b/tests/pytorch_wrapper/pt_max_test.py deleted file mode 100644 index d5d2a8a..0000000 --- a/tests/pytorch_wrapper/pt_max_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_max import PtMax - - -class TestPtMax(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMax() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "0", - False, - torch.tensor([4, 3, 5]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "1", - True, - torch.tensor([[3], [5]]) - ), - ( - torch.tensor([[[1, 5], [2, 8]], [[3, 4], [6, 7]]]), - "(0, 1)", - False, - torch.tensor([6, 8]) - ), - ( - # Reduce across all axes - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "", # Passing empty string to reduce across all dimensions - False, - torch.tensor(5) - ) - ] - - def test_max(self): - """Test torch.max behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected max values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_mean_test.py b/tests/pytorch_wrapper/pt_mean_test.py deleted file mode 100644 index 4f5f2c1..0000000 --- a/tests/pytorch_wrapper/pt_mean_test.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_mean import PtMean - - -class TestPtMean(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMean() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - # Float tensor cases - ( - torch.tensor([[1.0, 3.0, 2.0], [4.0, 0.0, 5.0]], dtype=torch.float), - "0", - False, - torch.tensor([2.5, 1.5, 3.5], dtype=torch.float) - ), - ( - torch.tensor([[1.0, 3.0, 2.0], [4.0, 0.0, 5.0]], dtype=torch.float), - "1", - True, - torch.tensor([[2.], [3.]], dtype=torch.float) - ), - ( - torch.tensor([[[1.0, 5.0], [2.0, 8.0]], [[3.0, 4.0], [6.0, 7.0]]], dtype=torch.float), - "(0, 1)", - False, - torch.tensor([3.0, 6.0], dtype=torch.float) - ), - ( - # Reduce across all axes - torch.tensor([[1.0, 3.0, 2.0], [4.0, 0.0, 5.0]], dtype=torch.float), - "", # Passing empty string to reduce across all dimensions - False, - torch.tensor(2.5, dtype=torch.float) - ), - # Complex tensor cases - ( - torch.tensor([[1 + 1j, 3 + 3j, 2 + 2j], [4 + 4j, 0 + 0j, 5 + 5j]], dtype=torch.complex64), - "0", - False, - torch.tensor([2.5 + 2.5j, 1.5 + 1.5j, 3.5 + 3.5j], dtype=torch.complex64) - ), - ( - torch.tensor([[1 + 1j, 3 + 3j, 2 + 2j], [4 + 4j, 0 + 0j, 5 + 5j]], dtype=torch.complex64), - "1", - True, - torch.tensor([[2. + 2j], [3. + 3j]], dtype=torch.complex64) - ), - ( - torch.tensor([[[1 + 1j, 5 + 5j], [2 + 2j, 8 + 8j]], [[3 + 3j, 4 + 4j], [6 + 6j, 7 + 7j]]], dtype=torch.complex64), - "(0, 1)", - False, - torch.tensor([3. + 3j, 6. + 6j], dtype=torch.complex64) - ), - ( - # Reduce across all axes - torch.tensor([[1 + 1j, 3 + 3j, 2 + 2j], [4 + 4j, 0 + 0j, 5 + 5j]], dtype=torch.complex64), - "", # Passing empty string to reduce across all dimensions - False, - torch.tensor(2.5 + 2.5j, dtype=torch.complex64) - ) - ] - - def test_mean(self): - """Test torch.mean behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected mean values - self.assertTrue(torch.allclose(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_median_test.py b/tests/pytorch_wrapper/pt_median_test.py deleted file mode 100644 index 15283c5..0000000 --- a/tests/pytorch_wrapper/pt_median_test.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_median import PtMedian - - -class TestPtMedian(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMedian() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 3, 2], [2, 1, 3], [4, 0, 5]]), - "0", - False, - torch.tensor([2, 1, 3]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "0", - False, - torch.tensor([1, 0, 2]) # Fix: torch.median returns the lower value when between two numbers - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "1", - True, - torch.tensor([[2], [4]]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5], [7, 8, 6], [9, 2, 10]]), - "0", - False, - torch.tensor([4, 2, 5]) - ), - ( - torch.tensor([[1, 3, 2, 8], [4, 0, 5, 6], [7, 8, 6, 9]]), - "1", - False, - torch.tensor([2, 4, 7]) - ) - ] - - def test_median(self): - """Test torch.median behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected median values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_min_test.py b/tests/pytorch_wrapper/pt_min_test.py deleted file mode 100644 index f70194f..0000000 --- a/tests/pytorch_wrapper/pt_min_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_min import PtMin - - -class TestPtMin(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMin() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "0", - False, - torch.tensor([1, 0, 2]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "1", - True, - torch.tensor([[1], [0]]) - ), - ( - torch.tensor([[[1, 5], [2, 8]], [[3, 4], [6, 7]]]), - "(0, 1)", - False, - torch.tensor([1, 4]) - ), - ( - # Reduce across all axes - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "", # Passing empty string to reduce across all dimensions - False, - torch.tensor(0) - ) - ] - - def test_amin(self): - """Test torch.amin behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected min values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_mm_test.py b/tests/pytorch_wrapper/pt_mm_test.py deleted file mode 100644 index 33fb78f..0000000 --- a/tests/pytorch_wrapper/pt_mm_test.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_mm import PtMm # Updated import to PtMm - - -class TestPtMm(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMm() - - # Valid test cases: (Tensor A, Tensor B, Expected result) - self.valid_test_cases = [ - # Case 1: 2D x 2D (matrix-matrix multiplication) - (torch.tensor([[1.0, 2.0], [3.0, 4.0]]), torch.tensor([[5.0, 6.0], [7.0, 8.0]]), torch.tensor([[19.0, 22.0], [43.0, 50.0]])), - - # Case 2: 2D identity matrix multiplication (should remain the same) - (torch.eye(3), torch.eye(3), torch.eye(3)), - - # Case 3: Rectangular 2D matrix multiplication - (torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), torch.tensor([[7.0, 8.0], [9.0, 10.0], [11.0, 12.0]]), torch.tensor([[58.0, 64.0], [139.0, 154.0]])), - ] - - # Invalid test cases (should raise errors) - self.invalid_test_cases = [ - (torch.tensor([1.0, 2.0, 3.0]), torch.tensor([4.0, 5.0, 6.0])), # 1D x 1D (dot product not supported by mm) - (torch.tensor([[1.0, 2.0]]), torch.tensor([3.0, 4.0])), # 2D x 1D mismatch - (torch.ones(2, 3, 4), torch.ones(4, 5)), # 3D x 2D is invalid for mm - (torch.ones(2, 3, 4), torch.ones(2, 4, 5)), # 3D x 3D is invalid for mm - ] - - def test_matrix_multiplication(self): - """Test valid matrix multiplication cases.""" - for tens_a, tens_b, expected in self.valid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected matrix multiplication - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - - def test_invalid_multiplication(self): - """Test invalid cases where dimensions do not match.""" - for tens_a, tens_b in self.invalid_test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - with self.assertRaises(ValueError, msg=f"torch.mm() should fail for shapes {tens_a.shape} and {tens_b.shape}"): - self.node.f(tens_a, tens_b) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_mul_test.py b/tests/pytorch_wrapper/pt_mul_test.py deleted file mode 100644 index 8bff3f9..0000000 --- a/tests/pytorch_wrapper/pt_mul_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_mul import PtMul # Updated import to PtMul - - -class TestPtMul(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtMul() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 2.0, 3.0]), torch.tensor([4.0, 5.0, 6.0]), torch.tensor([4.0, 10.0, 18.0])), - (torch.ones(3, 3), torch.ones(3, 3), torch.ones(3, 3)), # 1 * 1 = 1 - (torch.zeros(2, 2), torch.ones(2, 2), torch.zeros(2, 2)), # 0 * 1 = 0 - (torch.tensor([[2.0], [3.0]]), torch.tensor([[3.0], [4.0]]), torch.tensor([[6.0], [12.0]])), # Element-wise multiplication - ] - - def test_multiplication(self): - """Test tensor multiplication.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected product - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_ne_test.py b/tests/pytorch_wrapper/pt_ne_test.py deleted file mode 100644 index 4816b21..0000000 --- a/tests/pytorch_wrapper/pt_ne_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_ne import PtNe # Updated import to PtNe - - -class TestPtNe(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtNe() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([1, 2, 3]), torch.tensor([1, 2, 3]), torch.tensor([False, False, False])), - (torch.tensor([1, 2, 3]), torch.tensor([3, 2, 1]), torch.tensor([True, False, True])), - (torch.ones(3, 3), torch.ones(3, 3), torch.full((3, 3), False, dtype=torch.bool)), - (torch.zeros(2, 2), torch.ones(2, 2), torch.full((2, 2), True, dtype=torch.bool)), - (torch.tensor([[1], [2]]), torch.tensor([[1], [3]]), torch.tensor([[False], [True]])), - ] - - def test_inequality(self): - """Test tensor element-wise inequality using torch.ne().""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected element-wise inequality - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_neg_test.py b/tests/pytorch_wrapper/pt_neg_test.py deleted file mode 100644 index 57c66e1..0000000 --- a/tests/pytorch_wrapper/pt_neg_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_neg import PtNeg # Updated import to PtNeg - - -class TestPtNeg(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtNeg() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1, -2, 3]), torch.tensor([-1, 2, -3])), - (torch.tensor([0, 5, -7]), torch.tensor([0, -5, 7])), - (torch.ones(3, 3), torch.full((3, 3), -1.0)), # Negation of ones - (torch.zeros(2, 2), torch.zeros(2, 2)), # Negation of zeros - (torch.tensor([[5], [-10]]), torch.tensor([[-5], [10]])), # Column vector case - ] - - def test_neg(self): - """Test tensor element-wise negation using torch.neg().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected negation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_ones_test.py b/tests/pytorch_wrapper/pt_ones_test.py deleted file mode 100644 index fc893af..0000000 --- a/tests/pytorch_wrapper/pt_ones_test.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_ones import PtOnes # Importing the PtOnes class -from pytorch_wrapper.utils import DTYPE_MAPPING # Importing the dtype mapping - - -class TestPtOnes(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtOnes() - - # Tensor size to test - self.size_str = "[2, 3]" # Using a small 2D tensor size for all tests - self.expected_shape = (2, 3) - - def test_ones_tensor_all_dtypes(self): - """Test tensor creation with ones for all supported data types.""" - for data_type, torch_dtype in DTYPE_MAPPING.items(): - with self.subTest(data_type=data_type): - result, = self.node.f(self.size_str, data_type) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(self.expected_shape), f"Expected shape {self.expected_shape}, got {result.shape}") - - # Ensure result has correct dtype - self.assertEqual(result.dtype, torch_dtype, f"Expected dtype {torch_dtype}, got {result.dtype}") - - # Ensure all elements are ones - expected = torch.ones(self.expected_shape, dtype=torch_dtype) - self.assertTrue(torch.equal(result, expected), f"Tensor values do not match expected ones tensor for dtype {data_type}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_pad_test.py b/tests/pytorch_wrapper/pt_pad_test.py deleted file mode 100644 index 5198658..0000000 --- a/tests/pytorch_wrapper/pt_pad_test.py +++ /dev/null @@ -1,50 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_pad import PtPad - - -class TestPtPad(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtPad() - - # Test cases: (Input tensor, Height, Width, Expected shape) - self.test_cases = [ - (torch.rand(1, 3, 16, 16), 32, 32, (1, 3, 32, 32)), # Pad 4D tensor - (torch.rand(3, 16, 16), 32, 32, (3, 32, 32)), # Pad 3D tensor - (torch.rand(1, 3, 16, 16), 16, 16, (1, 3, 16, 16)), # No padding, same size - ] - - def test_padding(self): - """Test tensor padding to specific sizes.""" - for tens, height, width, expected_shape in self.test_cases: - with self.subTest(height=height, width=width): - result, = self.node.f(tens, height, width) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result shape matches expected shape - self.assertEqual(result.shape, expected_shape, f"Expected shape {expected_shape}, got {result.shape}") - - def test_invalid_tensor_rank(self): - """Test that an invalid tensor rank raises an error.""" - tens = torch.rand(16, 16) # 2D tensor (invalid) - with self.assertRaises(ValueError, msg="Only rank 3 or 4 tensors are supported for padding."): - self.node.f(tens, 32, 32) - - def test_padding_smaller_than_tensor(self): - """Test that padding to a smaller size raises an error.""" - tens = torch.rand(1, 3, 16, 16) - with self.assertRaises(ValueError, msg="Specified dimensions must be greater than or equal to tensor dimensions."): - self.node.f(tens, 8, 8) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_permute_test.py b/tests/pytorch_wrapper/pt_permute_test.py deleted file mode 100644 index 04a8e74..0000000 --- a/tests/pytorch_wrapper/pt_permute_test.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_permute import PtPermute - - -class TestPtPermute(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtPermute() - - # Define test cases: (input_tensor, new_axes, expected_shape) - self.test_cases = [ - # Case 1: Basic 2D permutation - (torch.ones(2, 3), "[1, 0]", (3, 2)), # (2,3) -> (3,2) - - # Case 2: Permute dimensions of a 3D tensor - (torch.ones(2, 3, 4), "[2, 0, 1]", (4, 2, 3)), # (2,3,4) -> (4,2,3) - - # Case 3: Identity permutation (no change) - (torch.ones(2, 3, 4), "[0, 1, 2]", (2, 3, 4)), # (2,3,4) -> (2,3,4) - - # Case 4: Permute 4D tensor (like a channel-first transformation) - (torch.ones(2, 3, 96, 32), "[0, 3, 1, 2]", (2, 32, 3, 96)), # (2,3,96,32) -> (2,32,3,96) - - # Case 5: Swapping first and last dimensions - (torch.ones(5, 10, 15), "[2, 1, 0]", (15, 10, 5)), # (5,10,15) -> (15,10,5) - - # Case 6: Edge case with a single-dimension tensor - (torch.ones(10,), "[0]", (10,)), # (10,) -> (10,) (No change) - - # Case 7: Larger 5D tensor permutation - (torch.ones(2, 3, 4, 5, 6), "[4, 3, 2, 1, 0]", (6, 5, 4, 3, 2)), # Reverse all dimensions - ] - - def test_permute(self): - """Test tensor permutation operation with various dimension orders.""" - for input_tensor, new_axes, expected_shape in self.test_cases: - with self.subTest(input_shape=input_tensor.shape, new_axes=new_axes): - result, = self.node.f(input_tensor, new_axes) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected_shape), f"Expected shape {expected_shape}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after permute operation") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_pow_test.py b/tests/pytorch_wrapper/pt_pow_test.py deleted file mode 100644 index b6bde5f..0000000 --- a/tests/pytorch_wrapper/pt_pow_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_pow import PtPow - - -class TestPtPow(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtPow() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([2.0, 3.0, 4.0]), torch.tensor([3.0, 2.0, 1.0]), torch.tensor([8.0, 9.0, 4.0])), # 2^3, 3^2, 4^1 - (torch.ones(3, 3) * 4, torch.ones(3, 3) * 2, torch.ones(3, 3) * 16), # 4^2 = 16 - (torch.full((2, 2), 5.0), torch.full((2, 2), 3.0), torch.full((2, 2), 125.0)), # 5^3 = 125 - (torch.tensor([[2.0], [3.0]]), torch.tensor([[4.0], [5.0]]), torch.tensor([[16.0], [243.0]])), # 2^4 = 16, 3^5 = 243 - ] - - def test_power(self): - """Test tensor exponentiation.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected power computation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_predict_classification_conv_model_test.py b/tests/pytorch_wrapper/pt_predict_classification_conv_model_test.py deleted file mode 100644 index c99eda4..0000000 --- a/tests/pytorch_wrapper/pt_predict_classification_conv_model_test.py +++ /dev/null @@ -1,68 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_conv_model import PtnConvModel -from pytorch_wrapper.ptv_image_folder_dataset import PtvImageFolderDataset -from pytorch_wrapper.ptv_transforms_resize import PtvTransformsResize -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_predict_classification_model import PtPredictClassificationModel -from pytorch_wrapper.pt_load_model import PtLoadModel - -class TestPtPrediction(unittest.TestCase): - - def setUp(self): - """Set up test instance.""" - # Transform - compose_node = PtvTransformsResize() - transform = compose_node.f(256, 256)[0] - - # Dataset - self.node = PtvImageFolderDataset() - self.dataset = self.node.f("dog_and_cat/val", - transform=transform)[0] - - - # Model - self.model_node = PtnConvModel() - self.model = self.model_node.f( - input_dim="(3, 256, 256)", - penultimate_dim=0, - output_dim=2, - channel_list="[32,64,128,256,512]", # To 128, 64, 32, 16, 8 - kernel_size_list="[3,3,3,3,3]", - padding_list="[1,1,1,1,1]", - downsample_list="[True,True,True,True,True]" - )[0] - - # Load weights - epochs = 20 - self.load_model = PtLoadModel() - self.loaded_model = self.load_model.f(self.model,f"dog_cat_{epochs}_epochs_conv.pt") - - # Instantiates evaluation node - self.predict = PtPredictClassificationModel() - - def test_prediction(self): - """ - Tests prediction. - - Note that this test requires a trained model file on the file system. - Unit test will fail if you run this for the first time. - Run the unit test for training to generate the weight, and re-run this unit test. - """ - inputs, y = next(iter(self.dataset)) - class_id_to_name_map = {0:"cat", 1:"dog"} - class_name, class_id, prob = \ - self.predict.f(self.model, inputs, class_id_to_name_map, use_gpu=True) - self.assertTrue(prob > 0.8) - self.assertEqual(class_id, 0) - self.assertEqual(class_name, "cat") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_prod_test.py b/tests/pytorch_wrapper/pt_prod_test.py deleted file mode 100644 index 29fd1ec..0000000 --- a/tests/pytorch_wrapper/pt_prod_test.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_prod import PtProd - - -class TestPtProd(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtProd() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 3, 2], [2, 1, 3]]), - "0", - False, - torch.tensor([2, 3, 6]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "1", - True, - torch.tensor([[6], [0]]) - ), - ( - torch.tensor([[1, 3, 2], [4, 5, 6]]), - "0", - False, - torch.tensor([4, 15, 12]) - ), - ( - torch.tensor([[1, 3, 2], [4, 5, 6], [7, 8, 9]]), - "1", - False, - torch.tensor([6, 120, 504]) - ) - ] - - def test_prod(self): - """Test torch.prod behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected product values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_rand_int_test.py b/tests/pytorch_wrapper/pt_rand_int_test.py deleted file mode 100644 index 57c66e1..0000000 --- a/tests/pytorch_wrapper/pt_rand_int_test.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_neg import PtNeg # Updated import to PtNeg - - -class TestPtNeg(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtNeg() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1, -2, 3]), torch.tensor([-1, 2, -3])), - (torch.tensor([0, 5, -7]), torch.tensor([0, -5, 7])), - (torch.ones(3, 3), torch.full((3, 3), -1.0)), # Negation of ones - (torch.zeros(2, 2), torch.zeros(2, 2)), # Negation of zeros - (torch.tensor([[5], [-10]]), torch.tensor([[-5], [10]])), # Column vector case - ] - - def test_neg(self): - """Test tensor element-wise negation using torch.neg().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected negation - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_rand_test.py b/tests/pytorch_wrapper/pt_rand_test.py deleted file mode 100644 index c3ef56c..0000000 --- a/tests/pytorch_wrapper/pt_rand_test.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_rand import PtRand # Importing the PtRand class -from pytorch_wrapper.utils import DTYPE_MAPPING # Importing the dtype mapping - - -class TestPtRand(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtRand() - - # Tensor size to test - self.size_str = "[2, 3]" # Using a small 2D tensor size for all tests - self.expected_shape = (2, 3) - - # Only floating-point types are valid for torch.rand() - self.valid_dtypes = {k: v for k, v in DTYPE_MAPPING.items() if v in {torch.float32, torch.float16, torch.bfloat16, torch.float64}} - - def test_rand_tensor_all_floating_dtypes(self): - """Test random tensor creation for all supported floating-point data types.""" - for data_type, torch_dtype in self.valid_dtypes.items(): - with self.subTest(data_type=data_type): - result, = self.node.f(self.size_str, data_type) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(self.expected_shape), f"Expected shape {self.expected_shape}, got {result.shape}") - - # Ensure result has correct dtype - self.assertEqual(result.dtype, torch_dtype, f"Expected dtype {torch_dtype}, got {result.dtype}") - - # Ensure all elements are within range [0,1) - self.assertTrue(torch.all(result >= 0) and torch.all(result < 1), f"Tensor values are not in the range [0,1) for dtype {data_type}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_randn_test.py b/tests/pytorch_wrapper/pt_randn_test.py deleted file mode 100644 index 9022c1d..0000000 --- a/tests/pytorch_wrapper/pt_randn_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_rand_int import PtRandInt # Importing the PtRandInt class -from pytorch_wrapper.utils import DTYPE_MAPPING # Importing the dtype mapping - - -class TestPtRandInt(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtRandInt() - - # Tensor size to test - self.size_str = "[2, 3]" # Using a small 2D tensor size for all tests - self.expected_shape = (2, 3) - - # Only integer types are valid for torch.randint() - self.valid_dtypes = { - k: v for k, v in DTYPE_MAPPING.items() if v in {torch.int8, torch.int16, torch.int32, torch.int64, torch.uint8} - } - - # Define min and max values for each integer type - self.test_ranges = { - "int8": (-128, 127), - "int16": (-32768, 32767), - "int32": (-2147483648, 2147483647), - "int64": (-9223372036854775808, 9223372036854775807), - "uint8": (0, 255), - } - - def test_randint_tensor_all_integer_dtypes(self): - """Test random integer tensor creation for all supported integer data types.""" - for data_type, torch_dtype in self.valid_dtypes.items(): - min_value, max_value = self.test_ranges[data_type] - - with self.subTest(data_type=data_type, min_value=min_value, max_value=max_value): - result, = self.node.f(min_value, max_value, self.size_str, data_type) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(self.expected_shape), f"Expected shape {self.expected_shape}, got {result.shape}") - - # Ensure result has correct dtype - self.assertEqual(result.dtype, torch_dtype, f"Expected dtype {torch_dtype}, got {result.dtype}") - - # Ensure all elements are within range [min_value, max_value) - self.assertTrue(torch.all(result >= min_value), f"Tensor contains values less than min_value for dtype {data_type}") - self.assertTrue(torch.all(result < max_value), f"Tensor contains values greater than or equal to max_value for dtype {data_type}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_remainder_test.py b/tests/pytorch_wrapper/pt_remainder_test.py deleted file mode 100644 index fbd17d0..0000000 --- a/tests/pytorch_wrapper/pt_remainder_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_remainder import PtRemainder - - -class TestPtRemainder(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtRemainder() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([4.0, 10.0, 18.0]), torch.tensor([3.0, 4.0, 5.0]), torch.tensor([1.0, 2.0, 3.0])), - (torch.ones(3, 3) * 7, torch.ones(3, 3) * 3, torch.ones(3, 3) * 1), # 7 % 3 = 1 - (torch.full((2, 2), 9.0), torch.full((2, 2), 2.0), torch.full((2, 2), 1.0)), # 9 % 2 = 1 - (torch.tensor([[7.0], [15.0]]), torch.tensor([[2.0], [4.0]]), torch.tensor([[1.0], [3.0]])), # Element-wise remainder - ] - - def test_remainder(self): - """Test tensor remainder computation.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected remainder - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_reshape_test.py b/tests/pytorch_wrapper/pt_reshape_test.py deleted file mode 100644 index 5cbcdf0..0000000 --- a/tests/pytorch_wrapper/pt_reshape_test.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_reshape import PtReshape # Importing the PtReshape class - - -class TestPtReshape(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtReshape() - - # Define test cases: (input_tensor, new_shape, expected_shape) - self.test_cases = [ - # Case 1: Reshape a 2D tensor - (torch.ones(2, 3), "[3, 2]", (3, 2)), # (2,3) -> (3,2) - - # Case 2: Reshape a 3D tensor - (torch.ones(2, 3, 4), "[6, 4]", (6, 4)), # (2,3,4) -> (6,4) - - # Case 3: Using -1 for automatic inference - (torch.ones(2, 3, 4), "[2, -1]", (2, 12)), # (2,3,4) -> (2,12) - (torch.ones(6, 4), "[-1, 4]", (6, 4)), # (6,4) -> (6,4) - - # Case 4: Flattening a multi-dimensional tensor - (torch.ones(2, 3, 4), "[-1]", (24,)), # (2,3,4) -> (24,) - - # Case 5: Expanding dimensions - (torch.ones(6,), "[2, 3]", (2, 3)), # (6,) -> (2,3) - - # Case 6: Reshaping a 4D tensor - (torch.ones(2, 3, 4, 5), "[6, -1, 5]", (6, 4, 5)), # (2,3,4,5) -> (6,4,5) - - # Case 7: Edge case with 1D tensor - (torch.ones(10,), "[10, 1]", (10, 1)), # (10,) -> (10,1) - ] - - def test_reshape(self): - """Test tensor reshape operation with various shape orders.""" - for input_tensor, new_shape, expected_shape in self.test_cases: - with self.subTest(input_shape=input_tensor.shape, new_shape=new_shape): - result, = self.node.f(input_tensor, new_shape) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected_shape), f"Expected shape {expected_shape}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after reshape operation") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_scatter_test.py b/tests/pytorch_wrapper/pt_scatter_test.py deleted file mode 100644 index 8aa2e15..0000000 --- a/tests/pytorch_wrapper/pt_scatter_test.py +++ /dev/null @@ -1,51 +0,0 @@ -import os -import sys -import unittest -import torch -import ast - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_scatter import PtScatter - - -class TestPtScatter(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtScatter() - - # Test cases: (Target Tensor, Dim, Index Tensor (as string), Source Tensor (as string), Expected Output) - self.test_cases = [ - ( - torch.tensor([ - [10, 11, 12], - [21, 22, 23], - [31, 32, 33], - ]), - 0, - "[[0, 1, 0], [1, 1, 2]]", - "[[2, 4, 6], [4, 4, 2]]", - torch.tensor([ - [2, 11, 6], - [4, 4, 23], - [31, 32, 2], - ]) - ) - ] - - def test_scatter(self): - """Test torch.scatter behavior.""" - for tens, dim, index, src, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, index=index, src=src): - result, = self.node.f(tens, dim, index, src) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_sin_test.py b/tests/pytorch_wrapper/pt_sin_test.py deleted file mode 100644 index 25d0b3f..0000000 --- a/tests/pytorch_wrapper/pt_sin_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_sin import PtSin # Updated import to PtSin - - -class TestPtSin(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSin() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, torch.pi / 2, torch.pi], dtype=torch.float32), torch.sin(torch.tensor([0.0, torch.pi / 2, torch.pi], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.sin(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.sin(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.sin(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_sin(self): - """Test tensor element-wise sine using torch.sin().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected sin values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_sinh_test.py b/tests/pytorch_wrapper/pt_sinh_test.py deleted file mode 100644 index 9e9a360..0000000 --- a/tests/pytorch_wrapper/pt_sinh_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_sinh import PtSinh # Updated import to PtSinh - - -class TestPtSinh(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSinh() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32), torch.sinh(torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32))), # Edge cases - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.sinh(torch.tensor([0.5, -0.5], dtype=torch.float32))), # Common values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.sinh(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.sinh(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_sinh(self): - """Test tensor element-wise hyperbolic sine using torch.sinh().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected sinh values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_size_create_test.py b/tests/pytorch_wrapper/pt_size_create_test.py deleted file mode 100644 index a229ac8..0000000 --- a/tests/pytorch_wrapper/pt_size_create_test.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_size_create import PtSizeCreate - -class TestPtSizeCreate(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtSizeCreate() - - # Test cases with torch.Size objects - self.test_cases = [ - # Empty size (zero-rank tensor shape) - ("[]", torch.Size([])), - # Rank 1 (single-dimension size) - ("[3]", torch.Size([3])), - # Rank 2 (matrix size) - ("[3, 4]", torch.Size([3, 4])), - # Rank 3 (3D tensor size) - ("[2, 3, 4]", torch.Size([2, 3, 4])), - # Rank 4 (higher-dimensional tensor size) - ("[1, 2, 3, 4]", torch.Size([1, 2, 3, 4])), - # Rank 5 (very high-dimensional tensor size) - ("[5, 4, 3, 2, 1]", torch.Size([5, 4, 3, 2, 1])), - ] - - def test_create_size(self): - """Test PyTorch Size creation from various structured inputs.""" - for data_str, expected_size in self.test_cases: - with self.subTest(data=data_str): - retval = self.node.f(data_str)[0] - - # Ensure the returned value is a PyTorch Size - self.assertTrue(isinstance(retval, torch.Size), f"Expected Size, got {type(retval)}") - - # Ensure the value matches expected size - self.assertEqual(retval, expected_size, f"Value mismatch for input: {data_str}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_size_test.py b/tests/pytorch_wrapper/pt_size_test.py deleted file mode 100644 index c268f48..0000000 --- a/tests/pytorch_wrapper/pt_size_test.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_size import PtSize - -class TestPtSize(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtSize() - - # Test cases with torch.Tensor objects - self.test_cases = [ - # Rank 0 (scalar tensor) - (torch.tensor(42), torch.Size([])), - # Rank 1 (vector tensor) - (torch.tensor([1, 2, 3]), torch.Size([3])), - # Rank 2 (matrix tensor) - (torch.tensor([[1, 2], [3, 4]]), torch.Size([2, 2])), - # Rank 3 (3D tensor) - (torch.tensor([[[1], [2]], [[3], [4]]]), torch.Size([2, 2, 1])), - # Rank 4 (4D tensor) - (torch.tensor([[[[1, 2], [3, 4]]]]), torch.Size([1, 1, 2, 2])), - ] - - def test_extract_size(self): - """Test PyTorch Size extraction from tensors.""" - for tensor, expected_size in self.test_cases: - with self.subTest(data=tensor): - retval = self.node.f(tensor)[0] - - # Ensure the returned value is a PyTorch Size - self.assertTrue(isinstance(retval, torch.Size), f"Expected Size, got {type(retval)}") - - # Ensure the value matches expected size - self.assertEqual(retval, expected_size, f"Value mismatch for input: {tensor}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_size_to_numpy_test.py b/tests/pytorch_wrapper/pt_size_to_numpy_test.py deleted file mode 100644 index feca5ef..0000000 --- a/tests/pytorch_wrapper/pt_size_to_numpy_test.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import sys -import unittest -import torch -import numpy as np - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_size_to_numpy import PtSizeToNumpy - -class TestPtSizeToNumpy(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtSizeToNumpy() - - # Test cases with torch.Size objects - self.test_cases = [ - # Empty size (zero-rank tensor shape) - (torch.Size([]), np.array([], dtype=int)), - # Rank 1 (single-dimension size) - (torch.Size([3]), np.array([3], dtype=int)), - # Rank 2 (matrix size) - (torch.Size([3, 4]), np.array([3, 4], dtype=int)), - # Rank 3 (3D tensor size) - (torch.Size([2, 3, 4]), np.array([2, 3, 4], dtype=int)), - # Rank 4 (higher-dimensional tensor size) - (torch.Size([1, 2, 3, 4]), np.array([1, 2, 3, 4], dtype=int)), - # Rank 5 (very high-dimensional tensor size) - (torch.Size([5, 4, 3, 2, 1]), np.array([5, 4, 3, 2, 1], dtype=int)), - ] - - def test_convert_size_to_numpy(self): - """Test conversion of PyTorch Size to NumPy ndarray.""" - for torch_size, expected_array in self.test_cases: - with self.subTest(data=torch_size): - retval = self.node.f(torch_size)[0] - - # Ensure the returned value is a NumPy array - self.assertTrue(isinstance(retval, np.ndarray), f"Expected ndarray, got {type(retval)}") - - # Ensure the dtype is integer - self.assertEqual(retval.dtype, expected_array.dtype, f"Dtype mismatch for input: {torch_size}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_array.shape, - f"Shape mismatch for input: {torch_size} (Expected {expected_array.shape}, got {retval.shape})") - - # Ensure values match - np.testing.assert_array_equal(retval, expected_array, - f"Value mismatch for input: {torch_size}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_size_to_string_test.py b/tests/pytorch_wrapper/pt_size_to_string_test.py deleted file mode 100644 index 69f9b54..0000000 --- a/tests/pytorch_wrapper/pt_size_to_string_test.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_size_to_string import PtSizeToString - -class TestPtSizeToString(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtSizeToString() - - # Test cases with torch.Size objects - self.test_cases = [ - # Empty size (zero-rank tensor shape) - (torch.Size([]), "torch.Size([])"), - # Rank 1 (single-dimension size) - (torch.Size([3]), "torch.Size([3])"), - # Rank 2 (matrix size) - (torch.Size([3, 4]), "torch.Size([3, 4])"), - # Rank 3 (3D tensor size) - (torch.Size([2, 3, 4]), "torch.Size([2, 3, 4])"), - # Rank 4 (higher-dimensional tensor size) - (torch.Size([1, 2, 3, 4]), "torch.Size([1, 2, 3, 4])"), - # Rank 5 (very high-dimensional tensor size) - (torch.Size([5, 4, 3, 2, 1]), "torch.Size([5, 4, 3, 2, 1])"), - ] - - def test_convert_size_to_string(self): - """Test conversion of PyTorch Size to string.""" - for torch_size, expected_string in self.test_cases: - with self.subTest(data=torch_size): - retval = self.node.f(torch_size)[0] - - # Ensure the returned value is a string - self.assertTrue(isinstance(retval, str), f"Expected str, got {type(retval)}") - - # Ensure the value matches expected string - self.assertEqual(retval, expected_string, f"Value mismatch for input: {torch_size}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_sqrt_test.py b/tests/pytorch_wrapper/pt_sqrt_test.py deleted file mode 100644 index 1254d07..0000000 --- a/tests/pytorch_wrapper/pt_sqrt_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_sqrt import PtSqrt # Updated import to PtSqrt - - -class TestPtSqrt(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSqrt() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([1.0, 4.0, 9.0], dtype=torch.float32), torch.sqrt(torch.tensor([1.0, 4.0, 9.0], dtype=torch.float32))), # Perfect squares - (torch.tensor([0.5, 2.0, 3.0], dtype=torch.float32), torch.sqrt(torch.tensor([0.5, 2.0, 3.0], dtype=torch.float32))), # Common values - (torch.tensor([[1.5, 3.2], [4.7, 5.9]], dtype=torch.float32), torch.sqrt(torch.tensor([[1.5, 3.2], [4.7, 5.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 2.5, dtype=torch.float32), torch.sqrt(torch.full((2, 2), 2.5, dtype=torch.float32))), # Constant matrix - ] - - def test_sqrt(self): - """Test tensor element-wise square root using torch.sqrt().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected sqrt values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_squeeze_test.py b/tests/pytorch_wrapper/pt_squeeze_test.py deleted file mode 100644 index a3d79f8..0000000 --- a/tests/pytorch_wrapper/pt_squeeze_test.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_squeeze import PtSqueeze # Importing the PtSqueeze class - - -class TestPtSqueeze(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSqueeze() - - # Define test cases: (input_tensor, dim, expected_shape) - self.test_cases = [ - # Case 1: Squeezing a singleton dimension - (torch.ones(1, 3, 4), 0, (3, 4)), # (1,3,4) -> (3,4) - (torch.ones(2, 1, 4), 1, (2, 4)), # (2,1,4) -> (2,4) - - # Case 2: No change if dim is not a singleton - (torch.ones(2, 3, 4), 1, (2, 3, 4)), # (2,3,4) -> (2,3,4) - - # Case 3: Multiple singleton dimensions, squeezing one - (torch.ones(1, 2, 1, 4), 2, (1, 2, 4)), # (1,2,1,4) -> (1,2,4) - - # Case 4: Squeezing a negative index - (torch.ones(2, 3, 1), -1, (2, 3)), # (2,3,1) -> (2,3) - - # Case 5: Squeezing all size 1 dimensions - (torch.ones(1, 1, 1), 0, (1, 1)), # (1,1,1) -> (1,1) - (torch.ones(1, 1, 1), 1, (1, 1)), # (1,1,1) -> (1,1) - (torch.ones(1, 1, 1), 2, (1, 1)), # (1,1,1) -> (1,1) - ] - - def test_squeeze(self): - """Test tensor squeeze operation on various dimensions.""" - for input_tensor, dim, expected_shape in self.test_cases: - with self.subTest(input_shape=input_tensor.shape, dim=dim): - result, = self.node.f(input_tensor, dim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected_shape), f"Expected shape {expected_shape}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after squeeze operation") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_std_test.py b/tests/pytorch_wrapper/pt_std_test.py deleted file mode 100644 index 3e46908..0000000 --- a/tests/pytorch_wrapper/pt_std_test.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_std import PtStd - - -class TestPtStd(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtStd() - - # Define test cases with string-based dimensions - self.test_cases = [ - # Sample standard deviation (Bessel's correction) along dim=0 - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "0", - 1, - False, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=0, correction=1, keepdim=False) - ), - # Sample standard deviation along dim=1, with keepdim=True - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "1", - 1, - True, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=1, correction=1, keepdim=True) - ), - # Sample standard deviation across both axes (dim=(0,1)) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "(0, 1)", - 1, - False, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=(0, 1), correction=1, keepdim=False) - ), - # Sample standard deviation across all elements (dim=None) - Entire tensor - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "", - 1, - False, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), correction=1, keepdim=False) - ), - # Population standard deviation along dim=0 (correction=0) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "0", - 0, - False, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=0, correction=0, keepdim=False) - ), - # Population standard deviation along dim=1 with keepdim=True (correction=0) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "1", - 0, - True, - torch.std(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=1, correction=0, keepdim=True) - ) - ] - - def test_std(self): - """Test torch.std behavior.""" - for tens, dim, correction, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, correction=correction, keepdim=keepdim): - result, = self.node.f(tens, dim, correction, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected standard deviation values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_sub_test.py b/tests/pytorch_wrapper/pt_sub_test.py deleted file mode 100644 index 4894c0b..0000000 --- a/tests/pytorch_wrapper/pt_sub_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_sub import PtSub - - -class TestPtSub(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSub() - - # Test cases: (Tensor A, Tensor B, Expected result) - self.test_cases = [ - (torch.tensor([5.0, 7.0, 9.0]), torch.tensor([4.0, 5.0, 6.0]), torch.tensor([1.0, 2.0, 3.0])), - (torch.full((3, 3), 2.0), torch.ones(3, 3), torch.ones(3, 3)), - (torch.ones(2, 2), torch.ones(2, 2), torch.zeros(2, 2)), - (torch.tensor([[4.0], [6.0]]), torch.tensor([[3.0], [4.0]]), torch.tensor([[1.0], [2.0]])), - ] - - def test_subtraction(self): - """Test tensor subtraction.""" - for tens_a, tens_b, expected in self.test_cases: - with self.subTest(tens_a=tens_a, tens_b=tens_b): - result, = self.node.f(tens_a, tens_b) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected difference - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_sum_test.py b/tests/pytorch_wrapper/pt_sum_test.py deleted file mode 100644 index dd528ec..0000000 --- a/tests/pytorch_wrapper/pt_sum_test.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_sum import PtSum - - -class TestPtSum(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtSum() - - # Test cases: (Tensor, Dim (as string), keepdim, Expected result) - self.test_cases = [ - ( - torch.tensor([[1, 3, 2], [2, 1, 3]]), - "0", - False, - torch.tensor([3, 4, 5]) - ), - ( - torch.tensor([[1, 3, 2], [4, 0, 5]]), - "1", - True, - torch.tensor([[6], [9]]) - ), - ( - torch.tensor([[1, 3, 2], [4, 5, 6]]), - "0", - False, - torch.tensor([5, 8, 8]) - ), - ( - torch.tensor([[1, 3, 2], [4, 5, 6], [7, 8, 9]]), - "1", - False, - torch.tensor([6, 15, 24]) - ), - ( - torch.tensor([[1, 2], [3, 4]]), - "", - False, - torch.tensor(10) # Sum of all elements - ), - ( - torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]), - "(0, 1)", - False, - torch.tensor([16, 20]) # Sum over dimensions (0, 1) - ) - ] - - def test_sum(self): - """Test torch.sum behavior.""" - for tens, dim, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, keepdim=keepdim): - result, = self.node.f(tens, dim, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected sum values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_tan_test.py b/tests/pytorch_wrapper/pt_tan_test.py deleted file mode 100644 index 1346872..0000000 --- a/tests/pytorch_wrapper/pt_tan_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_tan import PtTan # Updated import to PtTan - - -class TestPtTan(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtTan() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, torch.pi / 4, -torch.pi / 4], dtype=torch.float32), torch.tan(torch.tensor([0.0, torch.pi / 4, -torch.pi / 4], dtype=torch.float32))), # Common angles - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.tan(torch.tensor([0.5, -0.5], dtype=torch.float32))), # General values - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.tan(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.tan(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_tan(self): - """Test tensor element-wise tangent using torch.tan().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected tan values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_tanh_test.py b/tests/pytorch_wrapper/pt_tanh_test.py deleted file mode 100644 index e2f0fc8..0000000 --- a/tests/pytorch_wrapper/pt_tanh_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_tanh import PtTanh # Updated import to PtTanh - - -class TestPtTanh(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtTanh() - - # Test cases: (Tensor A, Expected result) - self.test_cases = [ - (torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32), torch.tanh(torch.tensor([0.0, 1.0, -1.0], dtype=torch.float32))), # Common values - (torch.tensor([0.5, -0.5], dtype=torch.float32), torch.tanh(torch.tensor([0.5, -0.5], dtype=torch.float32))), # General cases - (torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32), torch.tanh(torch.tensor([[0.1, -0.3], [0.7, -0.9]], dtype=torch.float32))), # 2D case - (torch.full((2, 2), 0.6, dtype=torch.float32), torch.tanh(torch.full((2, 2), 0.6, dtype=torch.float32))), # Constant matrix - ] - - def test_tanh(self): - """Test tensor element-wise hyperbolic tangent using torch.tanh().""" - for tens_a, expected in self.test_cases: - with self.subTest(tens_a=tens_a): - result, = self.node.f(tens_a) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected tanh values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_to_image_transpose_test.py b/tests/pytorch_wrapper/pt_to_image_transpose_test.py deleted file mode 100644 index f6ad4f3..0000000 --- a/tests/pytorch_wrapper/pt_to_image_transpose_test.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import sys -import unittest -import torch -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.pt_to_image_transpose import PtToImageTranspose - - -class TestPtToImageTranspose(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtToImageTranspose() - - # Define test cases: (input_tensor, expected_shape) - self.test_cases = [ - # Case 1: 3D tensor (C, H, W) -> (H, W, C) - (torch.ones(3, 64, 128), (64, 128, 3)), # (3,64,128) -> (64,128,3) - - # Case 2: 4D tensor (N, C, H, W) -> (N, H, W, C) - (torch.ones(10, 3, 64, 128), (10, 64, 128, 3)), # (10,3,64,128) -> (10,64,128,3) - - # Case 3: Invalid input (2D tensor) - (torch.ones(64, 128), ValueError), # 2D tensors should raise an error - - # Case 4: Invalid input (5D tensor) - (torch.ones(10, 3, 64, 128, 2), ValueError), # 5D tensors should raise an error - ] - - def test_transpose(self): - """Test tensor to image transposition with valid and invalid cases.""" - for input_tensor, expected in self.test_cases: - with self.subTest(input_shape=input_tensor.shape): - if isinstance(expected, tuple): - # Valid cases - result, = self.node.f(input_tensor) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected), f"Expected shape {expected}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after transpose operation") - else: - # Invalid cases should raise an error - with self.assertRaises(expected): - self.node.f(input_tensor) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_to_numpy_test.py b/tests/pytorch_wrapper/pt_to_numpy_test.py deleted file mode 100644 index be55c92..0000000 --- a/tests/pytorch_wrapper/pt_to_numpy_test.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -import sys -import unittest -import torch -import numpy as np - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_to_numpy import PtToNumpy - -class TestPtToNumpy(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtToNumpy() - - # Test cases covering rank 0 (scalar) to rank 5 tensors - self.test_cases = [ - # Rank 0 (scalar) int32 - (torch.tensor(12345, dtype=torch.int32), np.array(12345, dtype=np.int32)), - # Rank 0 (scalar) float32 - (torch.tensor(12345.6, dtype=torch.float32), np.array(12345.6, dtype=np.float32)), - - # Rank 1 (1D array) int32 - (torch.tensor([1, 2, 3], dtype=torch.int32), np.array([1, 2, 3], dtype=np.int32)), - # Rank 1 (1D array) float32 - (torch.tensor([1.1, 2.2, 3.3], dtype=torch.float32), np.array([1.1, 2.2, 3.3], dtype=np.float32)), - - # Rank 2 (2D matrix) int32 - (torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.int32), np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32)), - # Rank 2 (2D matrix) float32 - (torch.tensor([[1.1, 2.2], [3.3, 4.4]], dtype=torch.float32), np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.float32)), - - # Rank 3 (3D tensor) int32 - (torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.int32), - np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=np.int32)), - # Rank 3 (3D tensor) float32 - (torch.tensor([[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]]], dtype=torch.float32), - np.array([[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]]], dtype=np.float32)), - ] - - def test_convert_tensor_to_numpy(self): - """Test conversion of PyTorch tensor to NumPy ndarray.""" - for torch_tensor, expected_array in self.test_cases: - with self.subTest(data=torch_tensor): - retval = self.node.f(torch_tensor)[0] - - # Ensure the returned value is a NumPy array - self.assertTrue(isinstance(retval, np.ndarray), f"Expected ndarray, got {type(retval)}") - - # Ensure the dtype matches - self.assertEqual(retval.dtype, expected_array.dtype, f"Dtype mismatch for input: {torch_tensor}") - - # Ensure the shape matches - self.assertEqual(retval.shape, expected_array.shape, - f"Shape mismatch for input: {torch_tensor} (Expected {expected_array.shape}, got {retval.shape})") - - # Ensure values match - np.testing.assert_array_equal(retval, expected_array, - f"Value mismatch for input: {torch_tensor}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_to_rgb_tensors_test.py b/tests/pytorch_wrapper/pt_to_rgb_tensors_test.py deleted file mode 100644 index 69f411a..0000000 --- a/tests/pytorch_wrapper/pt_to_rgb_tensors_test.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_to_rgb_tensors import PtToRgbTensors - - -class TestPtToRgbTensors(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtToRgbTensors() - - # Test cases: (Input tensor, Expected R, Expected G, Expected B) - self.test_cases = [ - # 3D Tensor: [H, W, C] - ( - torch.tensor([[[255, 128, 64], [0, 127, 255]]], dtype=torch.uint8), - torch.tensor([[255, 0]], dtype=torch.uint8), - torch.tensor([[128, 127]], dtype=torch.uint8), - torch.tensor([[64, 255]], dtype=torch.uint8), - ), - - # 4D Tensor: [B, H, W, C] - ( - torch.tensor( - [[[[255, 0, 0], [0, 255, 0]], [[0, 0, 255], [255, 255, 255]]]], dtype=torch.uint8 - ), - torch.tensor([[[255, 0], [0, 255]]], dtype=torch.uint8), - torch.tensor([[[0, 255], [0, 255]]], dtype=torch.uint8), - torch.tensor([[[0, 0], [255, 255]]], dtype=torch.uint8), - ), - ] - - def test_split_rgb(self): - """Test splitting RGB tensors correctly.""" - for tensor, expected_r, expected_g, expected_b in self.test_cases: - with self.subTest(tensor_shape=tensor.shape): - r, g, b = self.node.f(tensor) - - # Ensure return values are tensors - self.assertTrue(isinstance(r, torch.Tensor), "R is not a tensor") - self.assertTrue(isinstance(g, torch.Tensor), "G is not a tensor") - self.assertTrue(isinstance(b, torch.Tensor), "B is not a tensor") - - # Ensure shapes match - self.assertEqual(r.shape, expected_r.shape, f"R shape mismatch: expected {expected_r.shape}, got {r.shape}") - self.assertEqual(g.shape, expected_g.shape, f"G shape mismatch: expected {expected_g.shape}, got {g.shape}") - self.assertEqual(b.shape, expected_b.shape, f"B shape mismatch: expected {expected_b.shape}, got {b.shape}") - - # Ensure values match - torch.testing.assert_close(r, expected_r, msg="R values mismatch") - torch.testing.assert_close(g, expected_g, msg="G values mismatch") - torch.testing.assert_close(b, expected_b, msg="B values mismatch") - - def test_invalid_input(self): - """Test error handling for non-3-channel input.""" - invalid_tensor = torch.rand(1, 512, 512, 4) # 4 channels instead of 3 - with self.assertRaises(ValueError) as context: - self.node.f(invalid_tensor) - self.assertIn("Expected a 3-channel tensor", str(context.exception)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_train_classification_conv_model_test.py b/tests/pytorch_wrapper/pt_train_classification_conv_model_test.py deleted file mode 100644 index 295753a..0000000 --- a/tests/pytorch_wrapper/pt_train_classification_conv_model_test.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.ptn_conv_model import PtnConvModel -from pytorch_wrapper.pto_adam import PtoAdam -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_train_classification_model import PtTrainClassificationModel -from pytorch_wrapper.pt_save_model import PtSaveModel - - -class TestPtTrainConvModel(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - compose_node = PtvTransformsToTensor() - transform = compose_node.f()[0] - dataset_node = PtvDataset() - dataset = dataset_node.f("FashionMNIST", - True, # download - "", # root - '{"train": True}', - transform=transform)[0] - data_loader_node = PtDataLoader() - self.train_loader = data_loader_node.f( - dataset=dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - self.model_node = PtnConvModel() - self.model = self.model_node.f( - input_dim="(1, 28, 28)", - penultimate_dim=0, - output_dim=10, - channel_list="[32,64,128,256]", - kernel_size_list="[3,3,3,3]", - padding_list="[1,1,1,1]", - downsample_list="[True,True,True,True]" - )[0] - - self.optimizer = PtoAdam().f(self.model, 0.001, 0.9, 0.999)[0] - self.trainer = PtTrainClassificationModel() - self.save_model = PtSaveModel() - - def test_1(self): - epochs = 1 - trained_model = self.trainer.f(self.model, self.train_loader, self.optimizer, - epochs, # epochs - use_gpu=True)[0] - self.save_model.f(trained_model, f"fashion_mnist_{epochs}_epochs_conv.pt") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_train_classification_conv_model_test2.py b/tests/pytorch_wrapper/pt_train_classification_conv_model_test2.py deleted file mode 100644 index 1c38ad6..0000000 --- a/tests/pytorch_wrapper/pt_train_classification_conv_model_test2.py +++ /dev/null @@ -1,73 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.ptn_conv_model import PtnConvModel -from pytorch_wrapper.pto_adam import PtoAdam -from pytorch_wrapper.ptv_image_folder_dataset import PtvImageFolderDataset -from pytorch_wrapper.ptv_transforms_resize import PtvTransformsResize -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_train_classification_model import PtTrainClassificationModel -from pytorch_wrapper.pt_save_model import PtSaveModel - - -class TestPtTrainConvModel2(unittest.TestCase): - - @unittest.skipIf(os.getenv("RUN_SKIPPED_TESTS") != "1", "Skipping unless explicitly enabled") - def setUp(self): - """Set up test instance.""" - compose_node = PtvTransformsResize() - transform = compose_node.f(256, 256)[0] - self.node = PtvImageFolderDataset() - train_dataset = self.node.f("dog_and_cat/train", - transform=transform)[0] - train_data_loader_node = PtDataLoader() - val_dataset = self.node.f("dog_and_cat/val", - transform=transform)[0] - val_data_loader_node = PtDataLoader() - self.train_loader = train_data_loader_node.f( - dataset=train_dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - self.val_loader = val_data_loader_node.f( - dataset=val_dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - self.model_node = PtnConvModel() - self.model = self.model_node.f( - input_dim="(3, 256, 256)", - penultimate_dim=0, - output_dim=2, - channel_list="[32,64,128,256,512]", # To 128, 64, 32, 16, 8 - kernel_size_list="[3,3,3,3,3]", - padding_list="[1,1,1,1,1]", - downsample_list="[True,True,True,True,True]" - )[0] - - self.optimizer = PtoAdam().f(self.model, 0.0001, 0.9, 0.999)[0] - self.trainer = PtTrainClassificationModel() - self.save_model = PtSaveModel() - - @unittest.skipIf(os.getenv("RUN_SKIPPED_TESTS") != "1", "Skipping unless explicitly enabled") - def test_1(self): - epochs = 20 - trained_model = self.trainer.f(self.model, self.train_loader, self.optimizer, - epochs, # epochs - use_gpu=True, - val_loader=self.val_loader)[0] - self.save_model.f(trained_model, f"dog_cat_{epochs}_epochs_conv.pt") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_train_classification_model_test.py b/tests/pytorch_wrapper/pt_train_classification_model_test.py deleted file mode 100644 index 9edb822..0000000 --- a/tests/pytorch_wrapper/pt_train_classification_model_test.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.ptn_linear_model import PtnLinearModel -from pytorch_wrapper.pto_adam import PtoAdam -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor -from pytorch_wrapper.pt_data_loader import PtDataLoader -from pytorch_wrapper.pt_train_classification_model import PtTrainClassificationModel -from pytorch_wrapper.pt_save_model import PtSaveModel - - -class TestPtTrainModel(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - compose_node = PtvTransformsToTensor() - transform = compose_node.f()[0] - dataset_node = PtvDataset() - dataset = dataset_node.f("FashionMNIST", - True, # download - "", # root - '{"train": True}', - transform=transform)[0] - data_loader_node = PtDataLoader() - self.train_loader = data_loader_node.f( - dataset=dataset, - batch_size=32, - shuffle=True, - parameters='{"num_workers":1}' - )[0] - - self.model_node = PtnLinearModel() - self.model = self.model_node.f( - "784,180,42,10", # input dim for first layer, output dim for each layer - "True,True,True", # bias - 3 # num layers - )[0] - - self.optimizer = PtoAdam().f(self.model, 0.001, 0.9, 0.999)[0] - self.trainer = PtTrainClassificationModel() - self.save_model = PtSaveModel() - - def test_1(self): - epochs = 1 - trained_model = self.trainer.f(self.model, self.train_loader, self.optimizer, - epochs, # epochs - use_gpu=True)[0] - self.save_model.f(trained_model, f"fashion_mnist_{epochs}_epochs.pt") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_train_classification_model_with_dataset_loader_test.py b/tests/pytorch_wrapper/pt_train_classification_model_with_dataset_loader_test.py deleted file mode 100644 index 43fead0..0000000 --- a/tests/pytorch_wrapper/pt_train_classification_model_with_dataset_loader_test.py +++ /dev/null @@ -1,51 +0,0 @@ -import os -import sys -import unittest -import torch -import torch.nn as nn - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.ptn_linear_model import PtnLinearModel -from pytorch_wrapper.pto_adam import PtoAdam -from pytorch_wrapper.ptv_dataset_loader import PtvDatasetLoader -from pytorch_wrapper.pt_train_classification_model import PtTrainClassificationModel -from pytorch_wrapper.pt_save_model import PtSaveModel - - -class TestPtTrainModelWithDatasetLoader(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.dataset_loader_node = PtvDatasetLoader() - self.train_loader = self.dataset_loader_node.f( - "MNIST", - True, # download - "", # root - batch_size=128, - shuffle=True, - dataset_parameters='{"train": True}', - load_parameters='{"num_workers":1}' - )[0] - self.model_node = PtnLinearModel() - self.model = self.model_node.f( - "784,180,42,10", # input dim for first layer, output dim for each layer - "True,True,True", # bias - 3 # num layers - )[0] - - self.optimizer = PtoAdam().f(self.model, 0.001, 0.9, 0.999)[0] - self.trainer = PtTrainClassificationModel() - self.save_model = PtSaveModel() - - def test_1(self): - epochs = 2 - trained_model = self.trainer.f(self.model, self.train_loader, self.optimizer, - epochs, # epochs - use_gpu=True)[0] - self.save_model.f(trained_model, f"mnist_{epochs}_epochs.pt") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_unsqueeze_test.py b/tests/pytorch_wrapper/pt_unsqueeze_test.py deleted file mode 100644 index d9b97a7..0000000 --- a/tests/pytorch_wrapper/pt_unsqueeze_test.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_unsqueeze import PtUnsqueeze # Importing the PtUnsqueeze class - - -class TestPtUnsqueeze(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtUnsqueeze() - - # Define test cases: (input_tensor, dim, expected_shape) - self.test_cases = [ - # Case 1: Adding a singleton dimension at different positions - (torch.ones(3, 4), 0, (1, 3, 4)), # (3,4) -> (1,3,4) - (torch.ones(3, 4), 1, (3, 1, 4)), # (3,4) -> (3,1,4) - (torch.ones(3, 4), 2, (3, 4, 1)), # (3,4) -> (3,4,1) - - # Case 2: Adding a singleton dimension at negative indices - (torch.ones(3, 4), -1, (3, 4, 1)), # (3,4) -> (3,4,1) - (torch.ones(3, 4), -2, (3, 1, 4)), # (3,4) -> (3,1,4) - (torch.ones(3, 4), -3, (1, 3, 4)), # (3,4) -> (1,3,4) - - # Case 3: Adding multiple dimensions one by one - (torch.ones(3,), 0, (1, 3)), # (3,) -> (1,3) - (torch.ones(3,), 1, (3, 1)), # (3,) -> (3,1) - (torch.ones(3,), -1, (3, 1)), # (3,) -> (3,1) - - # Case 4: Expanding an already multi-dimensional tensor - (torch.ones(2, 3, 4), 1, (2, 1, 3, 4)), # (2,3,4) -> (2,1,3,4) - (torch.ones(2, 3, 4), -1, (2, 3, 4, 1)), # (2,3,4) -> (2,3,4,1) - ] - - def test_unsqueeze(self): - """Test tensor unsqueeze operation on various dimensions.""" - for input_tensor, dim, expected_shape in self.test_cases: - with self.subTest(input_shape=input_tensor.shape, dim=dim): - result, = self.node.f(input_tensor, dim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected_shape), f"Expected shape {expected_shape}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after unsqueeze operation") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_var_test.py b/tests/pytorch_wrapper/pt_var_test.py deleted file mode 100644 index 2908cbd..0000000 --- a/tests/pytorch_wrapper/pt_var_test.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_var import PtVar - - -class TestPtVar(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtVar() - - # Define test cases with string-based dimensions - self.test_cases = [ - # Sample variance (Bessel's correction) along dim=0 - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "0", - 1, - False, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=0, correction=1, keepdim=False) - ), - # Sample variance along dim=1, with keepdim=True - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "1", - 1, - True, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=1, correction=1, keepdim=True) - ), - # Sample variance across both axes (dim=(0,1)) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "(0, 1)", - 1, - False, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=(0, 1), correction=1, keepdim=False) - ), - # Sample variance across all elements (dim=None) - Entire tensor - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "", - 1, - False, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), correction=1, keepdim=False) - ), - # Population variance along dim=0 (correction=0) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "0", - 0, - False, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=0, correction=0, keepdim=False) - ), - # Population variance along dim=1 with keepdim=True (correction=0) - ( - torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), - "1", - 0, - True, - torch.var(torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), dim=1, correction=0, keepdim=True) - ) - ] - - def test_var(self): - """Test torch.var behavior.""" - for tens, dim, correction, keepdim, expected in self.test_cases: - with self.subTest(tens=tens, dim=dim, correction=correction, keepdim=keepdim): - result, = self.node.f(tens, dim, correction, keepdim) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected variance values - self.assertTrue(torch.allclose(result, expected, atol=1e-6), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_view_test.py b/tests/pytorch_wrapper/pt_view_test.py deleted file mode 100644 index a35dc48..0000000 --- a/tests/pytorch_wrapper/pt_view_test.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_view import PtView # Importing the PtView class - - -class TestPtView(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtView() - - # Define test cases: (input_tensor, new_shape, expected_shape) - self.test_cases = [ - # Case 1: Reshape a 2D tensor - (torch.ones(2, 3), "[3, 2]", (3, 2)), # (2,3) -> (3,2) - - # Case 2: Reshape a 3D tensor - (torch.ones(2, 3, 4), "[6, 4]", (6, 4)), # (2,3,4) -> (6,4) - - # Case 3: Using -1 for automatic inference - (torch.ones(2, 3, 4), "[2, -1]", (2, 12)), # (2,3,4) -> (2,12) - (torch.ones(6, 4), "[-1, 4]", (6, 4)), # (6,4) -> (6,4) - - # Case 4: Flattening a multi-dimensional tensor - (torch.ones(2, 3, 4), "[-1]", (24,)), # (2,3,4) -> (24,) - - # Case 5: Expanding dimensions - (torch.ones(6,), "[2, 3]", (2, 3)), # (6,) -> (2,3) - - # Case 6: Reshaping a 4D tensor - (torch.ones(2, 3, 4, 5), "[6, -1, 5]", (6, 4, 5)), # (2,3,4,5) -> (6,4,5) - - # Case 7: Edge case with 1D tensor - (torch.ones(10,), "[10, 1]", (10, 1)), # (10,) -> (10,1) - ] - - def test_view(self): - """Test tensor reshape operation with various shape orders.""" - for input_tensor, new_shape, expected_shape in self.test_cases: - with self.subTest(input_shape=input_tensor.shape, new_shape=new_shape): - result, = self.node.f(input_tensor, new_shape) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(expected_shape), f"Expected shape {expected_shape}, got {result.shape}") - - # Ensure result has the same dtype - self.assertEqual(result.dtype, input_tensor.dtype, "Dtype mismatch after view operation") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_where_test.py b/tests/pytorch_wrapper/pt_where_test.py deleted file mode 100644 index 3f343fe..0000000 --- a/tests/pytorch_wrapper/pt_where_test.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_where import PtWhere - - -class TestPtWhere(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtWhere() - - # Test cases: (Condition Tensor, True Tensor, False Tensor, Expected Output) - self.test_cases = [ - ( - torch.tensor([[True, False], [False, True]]), - torch.tensor([[1, 2], [3, 4]]), - torch.tensor([[5, 6], [7, 8]]), - torch.tensor([[1, 6], [7, 4]]) - ), - ( - torch.tensor([True, False, True]), - torch.tensor([10, 20, 30]), - torch.tensor([100, 200, 300]), - torch.tensor([10, 200, 30]) - ), - ( - torch.tensor([[False, False], [True, True]]), - torch.tensor([[1.5, 2.5], [3.5, 4.5]]), - torch.tensor([[5.5, 6.5], [7.5, 8.5]]), - torch.tensor([[5.5, 6.5], [3.5, 4.5]]) - ), - ( - torch.tensor([[[True, False], [False, True]], [[False, True], [True, False]]]), - torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]), - torch.tensor([[[9, 10], [11, 12]], [[13, 14], [15, 16]]]), - torch.tensor([[[1, 10], [11, 4]], [[13, 6], [7, 16]]]) - ), - ] - - def test_where(self): - """Test torch.where behavior.""" - for condition_tens, true_tens, false_tens, expected in self.test_cases: - with self.subTest(condition_tens=condition_tens, true_tens=true_tens, false_tens=false_tens): - result, = self.node.f(condition_tens, true_tens, false_tens) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result matches expected values - self.assertTrue(torch.equal(result, expected), f"Expected {expected}, got {result}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/pt_zeros_test.py b/tests/pytorch_wrapper/pt_zeros_test.py deleted file mode 100644 index 3cfda36..0000000 --- a/tests/pytorch_wrapper/pt_zeros_test.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import sys -import unittest -import torch - - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.pt_zeros import PtZeros # Importing the PtZeros class -from pytorch_wrapper.utils import DTYPE_MAPPING # Importing the dtype mapping - - -class TestPtZeros(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.node = PtZeros() - - # Tensor size to test - self.size_str = "[2, 3]" # Using a small 2D tensor size for all tests - self.expected_shape = (2, 3) - - def test_zeros_tensor_all_dtypes(self): - """Test tensor creation with zeros for all supported data types.""" - for data_type, torch_dtype in DTYPE_MAPPING.items(): - with self.subTest(data_type=data_type): - result, = self.node.f(self.size_str, data_type) - - # Ensure return value is a tensor - self.assertTrue(isinstance(result, torch.Tensor), "Output is not a tensor") - - # Ensure result has correct shape - self.assertEqual(result.shape, torch.Size(self.expected_shape), f"Expected shape {self.expected_shape}, got {result.shape}") - - # Ensure result has correct dtype - self.assertEqual(result.dtype, torch_dtype, f"Expected dtype {torch_dtype}, got {result.dtype}") - - # Ensure all elements are zeros - expected = torch.zeros(self.expected_shape, dtype=torch_dtype) - self.assertTrue(torch.equal(result, expected), f"Tensor values do not match expected zeros tensor for dtype {data_type}") - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptn_conv_model_def_test.py b/tests/pytorch_wrapper/ptn_conv_model_def_test.py deleted file mode 100644 index 2b3b812..0000000 --- a/tests/pytorch_wrapper/ptn_conv_model_def_test.py +++ /dev/null @@ -1,158 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_conv_model_def import ConvModel, ConvSingleLayer - - -class TestPtnConvModelDef(unittest.TestCase): - def setUp(self): - """Setup method for initializing test conditions.""" - pass - - def test_single_layer_1_with_padding(self): - """Test ConvSingleLayer with padding=1, no downsampling.""" - model = ConvSingleLayer( - in_channels=4, - out_channels=32, - kernel_size=3, - padding=1, - downsample=False, - apply_activation=True) - x = torch.ones(1, 4, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([1, 32, 28, 28])) - - def test_single_layer_no_padding(self): - """Test ConvSingleLayer with padding=0, no downsampling.""" - model = ConvSingleLayer( - in_channels=4, - out_channels=32, - kernel_size=3, - padding=0, - downsample=False, - apply_activation=True) - x = torch.ones(1, 4, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([1, 32, 26, 26])) - - def test_single_layer_3_no_padding_downsample(self): - """Test ConvSingleLayer with padding=0 and downsampling enabled.""" - model = ConvSingleLayer( - in_channels=4, - out_channels=32, - kernel_size=3, - padding=0, - downsample=True, - apply_activation=True) - x = torch.ones(1, 4, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([1, 32, 13, 13])) - - def test_1(self): - """Test ConvModel with a single convolutional layer, checking output size.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32], - kernel_size_list=[3], - padding_list=[1], - downsample_list=[False]) - - x = torch.ones(1, 4, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([1, 10])) - - def test_2(self): - """Test ConvModel intermediate convolution layers' output size.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32], - kernel_size_list=[3], - padding_list=[1], - downsample_list=[False]) - - x = torch.ones(1, 4, 28, 28) - for c in model.conv_layers: - x = c(x) - out = x - self.assertEqual(out.size(), torch.Size([1, 32, 28, 28])) - - def test_3(self): - """Test ConvModel with two convolutional layers and downsampling enabled.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32,64], - kernel_size_list=[3,3], - padding_list=[1,1], - downsample_list=[True,True]) - - x = torch.ones(1, 4, 28, 28) - for c in model.conv_layers: - x = c(x) - out = x - self.assertEqual(out.size(), torch.Size([1, 64, 7, 7])) - - def test_4(self): - """Test ConvModel with three convolutional layers and downsampling enabled.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32,64,128], - kernel_size_list=[3,3,3], - padding_list=[1,1,1], - downsample_list=[True,True,True]) - - x = torch.ones(1, 4, 28, 28) - for c in model.conv_layers: - x = c(x) - out = x - self.assertEqual(out.size(), torch.Size([1, 128, 3, 3])) - - def test_5(self): - """Test ConvModel with four convolutional layers and downsampling enabled.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32,64,128,256], - kernel_size_list=[3,3,3,3], - padding_list=[1,1,1,1], - downsample_list=[True,True,True,True]) - - x = torch.ones(1, 4, 28, 28) - for c in model.conv_layers: - x = c(x) - out = x - self.assertEqual(out.size(), torch.Size([1, 256, 1, 1])) - - def test_6(self): - """Test ConvModel with five convolutional layers, last layer without downsampling.""" - model = ConvModel( - input_dim=(4, 28, 28), - penultimate_dim=0, - output_dim=10, - channel_list=[32,64,128,256,512], - kernel_size_list=[3,3,3,3,1], - padding_list=[1,1,1,1,0], - downsample_list=[True,True,True,True,False]) - - x = torch.ones(1, 4, 28, 28) - for c in model.conv_layers: - x = c(x) - out = x - self.assertEqual(out.size(), torch.Size([1, 512, 1, 1])) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptn_conv_model_test.py b/tests/pytorch_wrapper/ptn_conv_model_test.py deleted file mode 100644 index 9e6564e..0000000 --- a/tests/pytorch_wrapper/ptn_conv_model_test.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_conv_model import PtnConvModel - - -class TestPtnConvModel(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.model_node = PtnConvModel() - - def test_forward(self): - model = self.model_node.f( - input_dim="(4, 28, 28)", - penultimate_dim=0, - output_dim=10, - channel_list="[32,64,128,256]", - kernel_size_list="[3,3,3,3]", - padding_list="[1,1,1,1]", - downsample_list="[True,True,True,True]" - )[0] - bs = 2 - x = torch.ones(bs, 4, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([bs, 10])) - - def test_rank3_input(self): - model = self.model_node.f( - input_dim="(1, 28, 28)", - penultimate_dim=0, - output_dim=10, - channel_list="[32,64,128,256]", - kernel_size_list="[3,3,3,3]", - padding_list="[1,1,1,1]", - downsample_list="[True,True,True,True]" - )[0] - bs = 2 - x = torch.ones(bs, 28, 28) - out = model(x) - self.assertEqual(out.size(), torch.Size([bs, 10])) - - def test_rank2_input(self): - model = self.model_node.f( - input_dim="(1, 28, 28)", - penultimate_dim=0, - output_dim=10, - channel_list="[32,64,128,256]", - kernel_size_list="[3,3,3,3]", - padding_list="[1,1,1,1]", - downsample_list="[True,True,True,True]" - )[0] - bs = 2 - x = torch.ones(bs, 28) - with self.assertRaises(ValueError) as context: - model(x) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptn_linear_model_test.py b/tests/pytorch_wrapper/ptn_linear_model_test.py deleted file mode 100644 index 124a15a..0000000 --- a/tests/pytorch_wrapper/ptn_linear_model_test.py +++ /dev/null @@ -1,29 +0,0 @@ -import os -import sys -import unittest -import torch - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptn_linear_model import PtnLinearModel # Updated import to PtnLinear - - -class TestPtnLinearModel(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - self.model_node = PtnLinearModel() - self.model = self.model_node.f( - "784,180,42,10", # input dim for first layer, output dim for each layer - "True,True,True", # bias - 3 # num layers - )[0] # HINADA note: Using roughly 0.23x ratio for reduction - - def test_forward(self): - x = torch.ones(4, 28, 28) - out = self.model(x) - self.assertEqual(out.size(), torch.Size([4, 10])) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptv_dataset_loader_test.py b/tests/pytorch_wrapper/ptv_dataset_loader_test.py deleted file mode 100644 index 0d01690..0000000 --- a/tests/pytorch_wrapper/ptv_dataset_loader_test.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -import sys -import unittest -import torch -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptv_dataset_loader import PtvDatasetLoader - -class TestPtDataLoader(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.dataset_loader_node = PtvDatasetLoader() - - def test1(self): - """Tests downloading data and checks dimension""" - bs = 2 - train_data = self.dataset_loader_node.f( - "MNIST", - True, # download - "", # root - batch_size=bs, - shuffle=True, - dataset_parameters='{"train": True}', - load_parameters='{"num_workers":1}' - )[0] - - x, y = next(iter(train_data)) - self.assertEqual(x.size(), torch.Size([bs, 1, 28, 28])) - self.assertEqual(y.size(), torch.Size([bs])) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptv_dataset_test.py b/tests/pytorch_wrapper/ptv_dataset_test.py deleted file mode 100644 index 3eeffba..0000000 --- a/tests/pytorch_wrapper/ptv_dataset_test.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -import sys -import unittest - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptv_dataset import PtvDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor - -class TestPtvDataset(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtvDataset() - self.compose_node = PtvTransformsToTensor() - - def test_no_transform(self): - """Tests downloading without transform""" - self.node.f("MNIST", - True, # download - "", # root - '{"train": True}', - transform=None) - - def test_with_transform(self): - """Tests downloading with transform""" - transform = self.compose_node.f()[0] - self.node.f("MNIST", - True, # download - "", # root - '{"train": False}', - transform=transform) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptv_image_folder_dataset_test.py b/tests/pytorch_wrapper/ptv_image_folder_dataset_test.py deleted file mode 100644 index bc9de3b..0000000 --- a/tests/pytorch_wrapper/ptv_image_folder_dataset_test.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -This unit test requires the dog_and_cat dataset to be set up under -project_root/datasets/. -""" -import os -import sys -import unittest - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptv_image_folder_dataset import PtvImageFolderDataset -from pytorch_wrapper.ptv_transforms_to_tensor import PtvTransformsToTensor - - -class TestPtvImageDataset(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.node = PtvImageFolderDataset() - self.compose_node = PtvTransformsToTensor() - - def test_with_tensor_transform(self): - """Tests downloading with transform""" - transform = self.compose_node.f()[0] - dc = self.node.f("dog_and_cat/train", - transform=transform)[0] - expected_classes = ["cats", "dogs"] - expected_dict = [("cats", 0), ("dogs", 1)] - for i, c in enumerate(dc.classes): - self.assertEqual(c, expected_classes[i]) - - for i, (k, w) in enumerate(dc.class_to_idx.items()): - self.assertEqual(k, expected_dict[i][0]) - self.assertEqual(w, expected_dict[i][1]) - - # Read data - data = next(iter(dc)) - - # Check data shape - self.assertEqual(data[0].size(), (3, 512, 512)) - - # Check class - self.assertTrue(data[1] == 0) # cat - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/ptv_transforms_resize_test.py b/tests/pytorch_wrapper/ptv_transforms_resize_test.py deleted file mode 100644 index ca6d386..0000000 --- a/tests/pytorch_wrapper/ptv_transforms_resize_test.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sys -import unittest -import torch -from PIL import Image -import numpy as np - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) -from pytorch_wrapper.ptv_transforms_resize import PtvTransformsResize - - -class TestPtvTransformsResize(unittest.TestCase): - def setUp(self): - """Set up test data.""" - self.compose_node = PtvTransformsResize() - self.height = 128 - self.width = 128 - - def test_with_transform(self): - """Tests the transformation output.""" - transform = self.compose_node.f(self.height, self.width)[0] - self.assertTrue(callable(transform), "Transform should be callable.") - - # Create a dummy image - img = Image.fromarray(np.random.randint(0, 256, (256, 256, 3), dtype=np.uint8)) - transformed_img = transform(img) - - # Check output type - self.assertIsInstance(transformed_img, torch.Tensor, "Output should be a PyTorch tensor.") - - # Check output shape - self.assertEqual(transformed_img.shape, (3, self.height, self.width), "Output shape should match target dimensions.") - - def test_default_parameters(self): - """Tests default transform parameters.""" - transform = self.compose_node.f(256, 256)[0] - self.assertTrue(callable(transform), "Default transform should be callable.") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/pytorch_wrapper/utils_test.py b/tests/pytorch_wrapper/utils_test.py deleted file mode 100644 index 7101006..0000000 --- a/tests/pytorch_wrapper/utils_test.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import sys -import unittest - -PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..")) -MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules") -sys.path.append(MODULE_ROOT) - -from pytorch_wrapper.utils import str_to_dim - - -class TestStrToDim(unittest.TestCase): - def setUp(self): - """Set up test instance.""" - pass - - def test_valid_integer(self): - """Test parsing a valid integer string.""" - self.assertEqual(str_to_dim("5"), 5) - - def test_valid_tuple(self): - """Test parsing a valid tuple string.""" - self.assertEqual(str_to_dim("(1, 2, 3)"), (1, 2, 3)) - - def test_valid_list(self): - """Test parsing a valid list string (should be converted to tuple).""" - self.assertEqual(str_to_dim("[4, 5, 6]"), (4, 5, 6)) - - def test_empty_string(self): - """Test empty string input should return None.""" - self.assertIsNone(str_to_dim("")) - - def test_invalid_string(self): - """Test invalid string input should raise ValueError.""" - with self.assertRaises(ValueError): - str_to_dim("invalid") - - def test_mixed_type_list(self): - """Test a list with mixed types should raise ValueError.""" - with self.assertRaises(ValueError): - str_to_dim("[1, 'a', 3]") - - def test_nested_tuple(self): - """Test a nested tuple should raise ValueError.""" - with self.assertRaises(ValueError): - str_to_dim("((1, 2), 3)") - - def test_dict_input(self): - """Test a dictionary input should raise ValueError.""" - with self.assertRaises(ValueError): - str_to_dim("{'a': 1, 'b': 2}") - -if __name__ == "__main__": - unittest.main() diff --git a/web/js/ShowTextGeneric.js b/web/js/ShowTextGeneric.js index 1a68f01..e56aa46 100644 --- a/web/js/ShowTextGeneric.js +++ b/web/js/ShowTextGeneric.js @@ -12,7 +12,7 @@ import { ComfyWidgets } from "../../../scripts/widgets.js"; app.registerExtension({ name: "HowToSD.ShowTextGeneric", async beforeRegisterNodeDef(nodeType, nodeData, app) { - if (["NumpyShow", "PtShowText", "PtShowSize", "PandasShowSeries"].includes(nodeData.name)) { // This needs to match NODE_CLASS_MAPPINGS in Python + if (["NumpyShow", "PandasShowSeries"].includes(nodeData.name)) { // This needs to match NODE_CLASS_MAPPINGS in Python function populate(text) { if (this.widgets) { // Clear all widgets on the node