diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/bmm_einsum_matmul.py b/ML/Pytorch/linkedin_posts/tensor_operations/bmm_einsum_matmul.py new file mode 100644 index 0000000..625e727 --- /dev/null +++ b/ML/Pytorch/linkedin_posts/tensor_operations/bmm_einsum_matmul.py @@ -0,0 +1,40 @@ +import torch +import torch.utils.benchmark as benchmark + +# Sample input batched matrices dimensions. +n_batch, n, m, k = 10, 64, 128, 32 + +# Setup code as a string to be reused across benchmarks +setup_code = ( + f'import torch; ' + f'x = torch.randn({n_batch}, {n}, {m}); ' + f'y = torch.randn({n_batch}, {m}, {k})') + +# Number of threads from torch, reused in all timers. +num_threads = torch.get_num_threads() + +# A list of methods and their stmt strings for the benchmark +methods = [ + ('bmm', 'torch.bmm(x, y)'), + ('matmul', 'torch.matmul(x, y)'), + ('einsum', "torch.einsum('bnm,bmk->bnk', x, y)"), +] + +# Run each benchmark for a number of times to ensure measurement stability +num_runs = 100 + +# Create benchmark objects and run them, collecting the results. +results = [ + benchmark.Timer( + stmt=stmt, + setup=setup_code, + num_threads=num_threads, + label="Batched Matrix Multiplication", + sub_label=f"Method: {label}", + description=f"{n_batch}x{n}x{m}x{k}", + ).timeit(num_runs) + for label, stmt in methods +] + +# Group the results into a Compare object and print the results table. +benchmark.Compare(results).print() diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/broadcast_elementwise.py b/ML/Pytorch/linkedin_posts/tensor_operations/broadcast_elementwise.py new file mode 100644 index 0000000..e69de29 diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/broadcast_mm.py b/ML/Pytorch/linkedin_posts/tensor_operations/broadcast_mm.py new file mode 100644 index 0000000..e69de29 diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/cat_vs_stack.py b/ML/Pytorch/linkedin_posts/tensor_operations/cat_vs_stack.py new file mode 100644 index 0000000..9eb1562 --- /dev/null +++ b/ML/Pytorch/linkedin_posts/tensor_operations/cat_vs_stack.py @@ -0,0 +1,14 @@ +import torch + +# ===== USING torch.cat ===== +# torch.cat concatenates tensors along an existing axis. +t1 = torch.randn(2, 3) +t2 = torch.randn(2, 3) + +cat_dim0 = torch.cat((t1, t2), dim=0) # shape: (4, 3) +cat_dim1 = torch.cat((t1, t2), dim=1) # shape: (2, 6) + +# ===== USING torch.stack ===== +# torch.stack concatenates tensors along a new axis, not existing one. +stack_dim0 = torch.stack((t1, t2), dim=0) # shape: 2x2x3 +stack_dim2 = torch.stack((t1, t2), dim=2) # shape: 2x3x2 diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/float64_float32_float16.py b/ML/Pytorch/linkedin_posts/tensor_operations/float64_float32_float16.py new file mode 100644 index 0000000..cf981ec --- /dev/null +++ b/ML/Pytorch/linkedin_posts/tensor_operations/float64_float32_float16.py @@ -0,0 +1,36 @@ +import torch + +device = "cuda" if torch.cuda.is_available() else "cpu" + +def measure_performance(matrix_type, n, device, num_runs=100): + matrix = torch.randn(n, n, dtype=matrix_type, device=device) + start_event = torch.cuda.Event(enable_timing=True) + end_event = torch.cuda.Event(enable_timing=True) + + # Warming up + for _ in range(5): + torch.matmul(matrix, matrix) + + # Measure performance + start_event.record() + for _ in range(num_runs): + torch.matmul(matrix, matrix) + end_event.record() + + # Synchronizes events to ensure the time is measured correctly + torch.cuda.synchronize() + return start_event.elapsed_time(end_event) / num_runs + +n = 2**11 +num_runs = 100 + +# Dictionary to store execution time for different data types +execution_times = { + 'float16': measure_performance(torch.float16, n, device, num_runs), + 'float32': measure_performance(torch.float32, n, device, num_runs), + 'float64': measure_performance(torch.float64, n, device, num_runs), +} + +print(f'Execution time ({device}):') +for dtype, time in execution_times.items(): + print(f'{dtype}: {time:.6f} ms') diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/torch_matrix_mult.py b/ML/Pytorch/linkedin_posts/tensor_operations/torch_matrix_mult.py new file mode 100644 index 0000000..36815ec --- /dev/null +++ b/ML/Pytorch/linkedin_posts/tensor_operations/torch_matrix_mult.py @@ -0,0 +1,14 @@ +import torch + +# Create two random matrices +a = torch.rand(2**10, 2**10) +b = torch.rand(2**10, 2**10) + +# using mm (note only works for 2D tensors) +c = torch.mm(a, b) + +# using matmul +c = torch.matmul(a, b) + +# using @ operator (note exact same as matmul) +c = a @ b diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/transpose_vs_permute.py b/ML/Pytorch/linkedin_posts/tensor_operations/transpose_vs_permute.py new file mode 100644 index 0000000..968a30d --- /dev/null +++ b/ML/Pytorch/linkedin_posts/tensor_operations/transpose_vs_permute.py @@ -0,0 +1,11 @@ +import torch + +# Create a 3D tensor with shape (2, 3, 4) +tensor = torch.rand(2, 3, 4) + +# We'll swap the first and second dimension using torch.transpose +transposed = tensor.transpose(0, 1) # shape: 3x2x4 + +# Now let's permute the tensor dimensions with torch.permute +permuted = tensor.permute(2, 0, 1) # shape: 4x2x3 +permuted_like_transpose = tensor.permute(1, 0, 2) # shape: 3x2x4 diff --git a/ML/Pytorch/linkedin_posts/tensor_operations/unsqueeze_and_squeeze.py b/ML/Pytorch/linkedin_posts/tensor_operations/unsqueeze_and_squeeze.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index cd1b57b..96edb3f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # requirements.txt file with basic libraries to install for a machine learning workflow - +# HELLO numpy pandas scikit-learn @@ -12,6 +12,7 @@ torchvision torchaudio transformers lightning +torchmetrics # all you need is xgboost xgboost