Fix add tensor

This commit is contained in:
lucasdelimanogueira 2024-04-27 17:24:55 -03:00
parent e28e4d5057
commit d29ad014bf
6 changed files with 125 additions and 18 deletions

Binary file not shown.

View file

@ -5,6 +5,8 @@
extern "C" {
Tensor* create_tensor(float* data, int* shape, int ndim) {
printf("Creating tensor\n");
Tensor* tensor = (Tensor*)malloc(sizeof(Tensor));
if (tensor == NULL) {
fprintf(stderr, "Memory allocation failed\n");
@ -51,12 +53,12 @@ extern "C" {
}
}
printf("]\n\n\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];
@ -65,6 +67,7 @@ extern "C" {
}
Tensor* add_tensor(Tensor* tensor1, Tensor* tensor2) {
printf("Adding tensor\n");
if (tensor1->ndim != tensor2->ndim) {
fprintf(stderr, "Tensors must have the same number of dimensions %d and %d for addition\n", tensor1->ndim, tensor2->ndim);
exit(1);
@ -135,4 +138,77 @@ extern "C" {
return create_tensor(result_data, shape, ndim);
}
Tensor* sub_tensor(Tensor* tensor1, Tensor* tensor2) {
printf("Adding tensor\n");
if (tensor1->ndim != tensor2->ndim) {
fprintf(stderr, "Tensors must have the same number of dimensions %d and %d for addition\n", tensor1->ndim, tensor2->ndim);
exit(1);
}
int ndim = tensor1->ndim;
int* shape = (int*)malloc(ndim * sizeof(int));
if (shape == NULL) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}
printf("Size: %d\n", tensor1->size);
printf("Data: [");
for (int i = 0; i < tensor1->size; i++) {
printf("%.2f", tensor1->data[i]);
if (i < tensor1->size - 1) {
printf(", ");
}
}
printf("]\n");
printf("Size: %d\n", tensor2->size);
printf("Data: [");
for (int i = 0; i < tensor2->size; i++) {
printf("%.2f", tensor2->data[i]);
if (i < tensor2->size - 1) {
printf(", ");
}
}
printf("]\n");
printf("Shapes : [");
for (int i = 0; i < tensor1->ndim; i++) {
printf("%d", tensor1->shape[i]);
if (i < tensor1->ndim - 1) {
printf(", ");
}
}
printf("]\n");
printf("Shapes : [");
for (int i = 0; i < tensor2->ndim; i++) {
printf("%d", tensor2->shape[i]);
if (i < tensor2->ndim - 1) {
printf(", ");
}
}
printf("]\n");
for (int i = 0; i < ndim; i++) {
if (tensor1->shape[i] != tensor2->shape[i]) {
fprintf(stderr, "Tensors must have the same shape %d and %d at index %d for addition\n", tensor1->shape[i], tensor2->shape[i], i);
exit(1);
}
shape[i] = tensor1->shape[i];
}
float* result_data = (float*)malloc(tensor1->size * sizeof(float));
if (result_data == NULL) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}
for (int i = 0; i < tensor1->size; i++) {
result_data[i] = tensor1->data[i] - tensor2->data[i];
}
return create_tensor(result_data, shape, ndim);
}
}

View file

@ -14,6 +14,7 @@ extern "C" {
float get_item(Tensor* tensor, int* indices);
Tensor* create_tensor(float* data, int* shape, int ndim);
Tensor* add_tensor(Tensor* tensor1, Tensor* tensor2);
Tensor* sub_tensor(Tensor* tensor1, Tensor* tensor2);
}
#endif /* TENSOR_H */

Binary file not shown.

View file

@ -12,21 +12,31 @@ class CTensor(ctypes.Structure):
class Tensor:
_C = ctypes.CDLL("../build/libtensor.so")
def __init__(self, data):
data, shape = self.flatten(data)
# Adjust the path to the shared library
self.data = (ctypes.c_float * len(data))(*data)
self.shape = shape
self.ndim = len(shape)
def __init__(self, data=None):
Tensor._C.create_tensor.argtypes = [ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_int), ctypes.c_int]
Tensor._C.create_tensor.restype = ctypes.POINTER(CTensor)
if data != None:
data, shape = self.flatten(data)
# Adjust the path to the shared library
self.data_ctype = (ctypes.c_float * len(data))(*data)
self.shape_ctype = (ctypes.c_int * len(shape))(*shape)
self.ndim_ctype = ctypes.c_int(len(shape))
self.tensor = Tensor._C.create_tensor(
self.data,
(ctypes.c_int * len(shape))(*shape),
ctypes.c_int(len(shape))
)
self.shape = shape
self.ndim = len(shape)
Tensor._C.create_tensor.argtypes = [ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_int), ctypes.c_int]
Tensor._C.create_tensor.restype = ctypes.POINTER(CTensor)
self.tensor = Tensor._C.create_tensor(
self.data_ctype,
self.shape_ctype,
self.ndim_ctype
)
else:
self.tensor = None,
self.shape = None,
self.ndim = None
def flatten(self, nested_list):
flat_data = []
@ -68,11 +78,28 @@ class Tensor:
result_tensor_ptr = Tensor._C.add_tensor(self.tensor, other.tensor)
result_data = [result_tensor_ptr.contents.data[i] for i in range(self.shape[0] * self.shape[1])]
result_shape = [result_tensor_ptr.contents.shape[i] for i in range(result_tensor_ptr.contents.ndim)]
result_data = Tensor()
result_data.tensor = result_tensor_ptr
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
return Tensor(result_data, result_shape)
return result_data
def __sub__(self, other):
if self.shape != other.shape:
raise ValueError("Tensors must have the same shape for addition")
Tensor._C.add_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.POINTER(CTensor)]
Tensor._C.add_tensor.restype = ctypes.POINTER(CTensor)
result_tensor_ptr = Tensor._C.sub_tensor(self.tensor, other.tensor)
result_data = Tensor()
result_data.tensor = result_tensor_ptr
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
return result_data
if __name__ == "__main__":
from tensor import Tensor
@ -82,7 +109,10 @@ if __name__ == "__main__":
a = Tensor([[1, 2, 3], [1, 2, 3]])
b = Tensor([[1, 2, 3], [1, 2, 3]])
c = a + b
c = a + b - b
print(c)
fim = time.time()
print(fim-ini)