From 06b82066aec3e3fe3609a3c67a1b95e514ef527b Mon Sep 17 00:00:00 2001 From: lucasdelimanogueira Date: Fri, 26 Apr 2024 00:33:28 -0300 Subject: [PATCH] Create and print a tensor --- build/Makefile | 29 ++++++++ build/libtensor.so | Bin 0 -> 16576 bytes python/__pycache__/tensor.cpython-39.pyc | Bin 0 -> 2653 bytes python/tensor.py | 54 ++++++++++++++ python/tests.ipynb | 90 +++++++++++++++++++++++ src/tensor.cpp | 67 +++++++++++++++++ src/tensor.h | 17 +++++ src/tensor.o | Bin 0 -> 3760 bytes 8 files changed, 257 insertions(+) create mode 100644 build/Makefile create mode 100755 build/libtensor.so create mode 100644 python/__pycache__/tensor.cpython-39.pyc create mode 100644 python/tensor.py create mode 100644 python/tests.ipynb create mode 100644 src/tensor.cpp create mode 100644 src/tensor.h create mode 100644 src/tensor.o diff --git a/build/Makefile b/build/Makefile new file mode 100644 index 0000000..78f3ec6 --- /dev/null +++ b/build/Makefile @@ -0,0 +1,29 @@ +# Compiler +CXX := g++ + +# Compiler flags +CXXFLAGS := -Wall -Werror -fpic + +# Source files +SRCS := ../src/tensor.cpp + +# Object files +OBJS := $(SRCS:.cpp=.o) + +# Target shared object file +TARGET := libtensor.so + +# Default target +all: $(TARGET) + +# Rule to build the shared object file +$(TARGET): $(OBJS) + $(CXX) -shared -o $@ $^ + +# Rule to compile each source file into an object file +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $^ -o $@ # Use -o $@ to specify the output file + +# Clean rule +clean: + $(RM) $(OBJS) $(TARGET) diff --git a/build/libtensor.so b/build/libtensor.so new file mode 100755 index 0000000000000000000000000000000000000000..01c161860fea80d9d729f5dda25a9a0d1e7b9866 GIT binary patch literal 16576 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 F{RiT7wq*bS literal 0 HcmV?d00001 diff --git a/python/__pycache__/tensor.cpython-39.pyc b/python/__pycache__/tensor.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27d992d959483ea5c1739f7d6c42f99081504d5e GIT binary patch literal 2653 zcmai0&2Jk;6rY)0dpC}grXg)f31C`;>K4TuD6Jq=6-|YZDpQe)gQaTZc*c&++MCRd zE7fu?Boc6`)H6bgkNKBI+&J~ZgW}V!=c1NuCu!5VLQ8fB7DC!xov2J6GII_Vc=Gb|+E&`vwImtT*3;IouLm~G zYDTw=Zdxt3pW4*4wrcG(tzo>C4rL=R7>BKm@gRE)l;W>g7%q-IqaeXQny+q^60u(e3$tA`Xp9OMf9j)7$d zT=5AXGbw&zZSFlE|H6J|W4_0Cg$<|&H?)N@SK%_V#XVsjj#&%~uEbGOPA@=wZ8;fTQl4fvciPk54I+~?XZ?+SRSx@xJa?Y>MlU9Cyj{1W# zD9-j~A&>PUFA@DSvf*fL!YAO$1;v0tTpwLnU9D{nyNRkL-OZ^}vb4ot0fL^!gv(oK z*+(E2T3QY(S3DxXWIrA=vSlRQbO<4Wasi$SII0773&cw2bcYAeDFFe~Po`;s}~5cR`{DRbj|dS4i{| zogAm6@v2<}YX!|*0vTQXPo+-Secn(Wy71omg9o^wyJ_Ab0c4wbo5(Ve0+BKikH{>I z=0F;A)0Br_s3gTr)A1F>r?ZQU&S>h2IUlYKGo7@(l*SDCLsAjT?eI8zzoK;IzN0I% z3JBxnpd7_Oo61FrFNh^^1+>URzQpJM8J#<0>}zRGFyBMV6i5y)(uV&Kn2Qz#d5{0d zEsC;5N%lR;?u2&)rB*LSk_Nrfbd2Qc6>|woaMLrkONkjBASrs~F`o#EYowc~k8ak7 z{Y`BuX}i)zU2f^D(jR8F(r?<f}V%HU`N$~Hjkrh}|HckBdL`o5VA^?hSf<6UJu z_!Kza1BOz|#T{)W<%xNp7~WGA8hrp#4a^mEE}E*~3QtJnnc#7=QbGy|k+O>Y**plN z;w)BpSu6tW(c%%xM_W(D^Q+q7fu=wOB&evMV#2wv6NkJGg-GkhY};rp^U&~`9&)eg zSTV;z%fC6G?yR0=D(R=zT{OTyASf~ z*nZ}I&$xZ!?(+0*fB4kR6l4*axBn3aiu+tfpeeD8iixs!8($H^g{xq?va*Y>ibbf6 z#W-mDeJZ@fZXvLCKE$^KUloiN$NV6eP#rJU9rFdnT*ehIdByQkHFO2j9CWnT)&=-0 zz#jpA4YsRc?*1Z@ahO=gyN>tHnCJj8HcR;h1ZEUI42iXf_cD_01lWGlDU-?N @@ c_int(2)\n", + "Tensor created successfully\n", + "Tensor information:\n", + "Number of dimensions: 2\n", + "Shape: [3, 3]\n", + "Data:\n", + "[0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90]\n" + ] + }, + { + "ename": "ValueError", + "evalue": "Number of indices must match the number of dimensions", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 6\u001b[0m\n\u001b[1;32m 4\u001b[0m shape \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m3\u001b[39m, \u001b[38;5;241m3\u001b[39m]\n\u001b[1;32m 5\u001b[0m tensor \u001b[38;5;241m=\u001b[39m Tensor(data, shape)\n\u001b[0;32m----> 6\u001b[0m \u001b[43mTensor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__getitem__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documentos/recreate_pytorch/foo/python/tensor.py:15\u001b[0m, in \u001b[0;36mTensor.__getitem__\u001b[0;34m(self, indices)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, indices):\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(indices) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mndim:\n\u001b[0;32m---> 15\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNumber of indices must match the number of dimensions\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 16\u001b[0m indices \u001b[38;5;241m=\u001b[39m (ctypes\u001b[38;5;241m.\u001b[39mc_int \u001b[38;5;241m*\u001b[39m \u001b[38;5;28mlen\u001b[39m(indices))(\u001b[38;5;241m*\u001b[39mindices)\n\u001b[1;32m 17\u001b[0m value \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlib\u001b[38;5;241m.\u001b[39mget_item(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtensor, indices) \n", + "\u001b[0;31mValueError\u001b[0m: Number of indices must match the number of dimensions" + ] + } + ], + "source": [ + "from tensor import Tensor\n", + "\n", + "data = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]\n", + "shape = [3, 3]\n", + "tensor = Tensor(data, shape)\n", + "tensor.shape\n", + "Tensor.__getitem__(tensor, [0, 0])" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-648269760\n" + ] + } + ], + "source": [ + "print(tensor[1, 1]) # Accessing an element" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/tensor.cpp b/src/tensor.cpp new file mode 100644 index 0000000..bcdbcb9 --- /dev/null +++ b/src/tensor.cpp @@ -0,0 +1,67 @@ +#include +#include +#include "tensor.h" + +extern "C" { + + Tensor *create_tensor(float *data, int *shape, int ndim) { + Tensor *tensor = (Tensor *)malloc(sizeof(Tensor)); + if (tensor == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(1); + } + tensor->data = data; + tensor->shape = shape; + tensor->ndim = ndim; + + tensor->strides = (int *)malloc(ndim * sizeof(int)); + if (tensor->strides == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(1); + } + int stride = 1; + for (int i = ndim - 1; i >= 0; i--) { + tensor->strides[i] = stride; + stride *= shape[i]; + } + + printf("Tensor created successfully\n"); + printf("Tensor information:\n"); + printf("Number of dimensions: %d\n", tensor->ndim); + printf("Shape: ["); + for (int i = 0; i < ndim; i++) { + printf("%d", tensor->shape[i]); + if (i < ndim - 1) { + printf(", "); + } + } + printf("]\n"); + + printf("Data:\n["); + for (int i = 0; i < stride; i++) { + printf("%.2f", tensor->data[i]); + if (i < stride - 1) { + printf(", "); + } + } + printf("]\n"); + + + return tensor; + } + + float get_item(Tensor *tensor, int *indices) { + int index = 0; + for (int i = 0; i < tensor->ndim; i++) { + index += indices[i] * tensor->strides[i]; + } + return tensor->data[index]; + } + + void free_tensor(Tensor *tensor) { + free(tensor->data); + free(tensor->shape); + free(tensor->strides); + free(tensor); + } +} diff --git a/src/tensor.h b/src/tensor.h new file mode 100644 index 0000000..f93b22a --- /dev/null +++ b/src/tensor.h @@ -0,0 +1,17 @@ +#ifndef TENSOR_H +#define TENSOR_H + +typedef struct { + float *data; + int *strides; + int *shape; + int ndim; +} Tensor; + +extern "C" { + Tensor *create_tensor(float *data, int *shape, int ndim); + float get_item(Tensor *tensor, int *indices); + void delete_tensor(Tensor* tensor); +} + +#endif /* TENSOR_H */ diff --git a/src/tensor.o b/src/tensor.o new file mode 100644 index 0000000000000000000000000000000000000000..237b41a16cfd3e0137c3b44eef9fa27a20f509d5 GIT binary patch literal 3760 zcmbtWU1%It6h56peDOu_Nfd;>R*SYtp|Kbt^vMT>Cady}a9AC)xH@=+j)1fcUDwT+ z=#YJvgEz>DcNVWEO<;{}kc1 zQG48NFYfknR;$cbO?9`7AU^f)j zsIndEhD*USG+NJap&7hd58-9T`$u;WZ!5oG?ly|5mVHmlp6jmNyK~ye70hKdk92R*4%GcgDN+$JoDgJjT~KzaWRC`%#bQ18B; zYuNE;5T`*hhep8qLmvlD_3aH#1(4$EUUszr6`F-UV3FF@zs>bCEqdnaxvFiV%eDvp zdeo*sAlUIuMz}alt5wiFeJe)0pj(Yj_`Y_~<>P@mND%gSK*|5!HoO;+Cw%$4HAU=c z9Mm6K!U%N2U+RLN=z_B@_#0jD*)I57h*SO|Z@1@�^n-4PVG*EnCs(J6nh+-F5g z7K`9LFL4in_|)|5$%*Os?BwJ;I~zYcadMi)A?H4BP_j~nX+ruvGh-QGEM+VxmaP&L z%}m}(!$rf2qap`s(=dcXTEnxH6bjvW>cP$xL_<7RX!Z63l5A{Xl zIVSN(IX}{c|GLB%^_utb5BmI{llTkVf2s@rQ;DD9{Lj1auS@(a=YQLUe^=rcIR7Uf z-(R2m68~M!|JBF$pSPb1k0R>7>}_F)<5Yh?|ER0K}S z-spn&@K-72>E{o2!BymukUQ?u-ACQuCNAC^3lc8g8=#ezb5>#zXUp{FOJZdj*@R{p zOBQG;{2YR|SSo>L7Q9Weki%~%>hcB4(C`~KT(T0$%Y1(^U)G9dp=g-aGTM+Q<5E0r zCUOSPn65^kt1#VA&*U46ViH11&d5%kA z;JgfQz8wD;_bJo=t^Ej(@9#Z@680a_#wT+82b2pmX@;pKlhoM%K!iX literal 0 HcmV?d00001