| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | #include <list> | 
					
						
							|  |  |  | #include <iostream> | 
					
						
							|  |  |  | #include <stdlib.h> | 
					
						
							|  |  |  | #include <algorithm> | 
					
						
							|  |  |  | #include <thrust/device_vector.h> | 
					
						
							|  |  |  | #include "lista.h" | 
					
						
							|  |  |  | #include "memory.h" | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | #include "pred.h" | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MAX_REC 200 | 
					
						
							|  |  |  | #define MAX_FIX_POINTS 100 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | memnode temp_storage[MAX_REC]; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*List used to store information (address, size, etc.) about facts and rule results loaded in the GPU*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | list<memnode> GPUmem; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*List used to store information about rule results offloaded from the GPU to the CPU*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | list<memnode> CPUmem; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Auxiliary function to sort rule list*/ | 
					
						
							|  |  |  | bool comparer(const rulenode &r1, const rulenode &r2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (r1.name > r2.name);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*Used in search functions to compare iterations*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | bool compareiteration(const memnode &r1, const memnode &r2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (r1.iteration < r2.iteration);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Used in search functions to compare names*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | bool comparename(const memnode &r1, const memnode &r2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (r1.name > r2.name);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Linear search of 'name' fact*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | template<class InputIterator> | 
					
						
							|  |  |  | InputIterator buscarhecho(InputIterator first, InputIterator last, int name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while(first!=last)  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		if(first->name == name && first->isrule == 0) return first; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 			++first; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return last; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Finds all results of rule 'name' in iteration 'itr' in both CPU and GPU memory. Every result found is removed from its respective list*/ | 
					
						
							|  |  |  | list<memnode>::iterator buscarpornombre(int name, int itr, int *totalrows, int *gpunum, int *cpunum) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	int x = 0, sum = 0; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	memnode temp; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	list<memnode>::iterator i; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	temp.iteration = itr; | 
					
						
							|  |  |  | 	pair<list<memnode>::iterator, list<memnode>::iterator> rec = equal_range(GPUmem.begin(), GPUmem.end(), temp, compareiteration); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	while(rec.first != rec.second) | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if(rec.first->name == name && rec.first->isrule == 1) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			temp_storage[x] = *rec.first; | 
					
						
							|  |  |  | 			rec.first = GPUmem.erase(rec.first); | 
					
						
							|  |  |  | 			sum += temp_storage[x].rows; | 
					
						
							|  |  |  | 			x++; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*gpunum = x; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	temp.name = name; | 
					
						
							|  |  |  | 	temp.isrule = 1; | 
					
						
							|  |  |  | 	i = GPUmem.insert(rec.first, temp); | 
					
						
							|  |  |  | 	rec = equal_range(CPUmem.begin(), CPUmem.end(), temp, compareiteration); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(rec.first != rec.second) | 
					
						
							|  |  |  | 	{				 | 
					
						
							|  |  |  | 		if(rec.first->name == name && rec.first->isrule == 1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			temp_storage[x] = *rec.first; | 
					
						
							|  |  |  | 			rec.first = CPUmem.erase(rec.first); | 
					
						
							|  |  |  | 			sum += temp_storage[x].rows; | 
					
						
							|  |  |  | 			x++; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*totalrows = sum; | 
					
						
							|  |  |  | 	*cpunum = x; | 
					
						
							|  |  |  | 	return i; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | list<memnode>::iterator buscarpornombrecpu(int name, int itr, int *totalrows, int *gpunum, int *cpunum) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	int x = 0, sum = 0; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	memnode temp; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	list<memnode>::iterator i; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	temp.iteration = itr; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	pair<list<memnode>::iterator, list<memnode>::iterator> rec = equal_range(GPUmem.begin(), GPUmem.end(), temp, compareiteration); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	while(rec.first != rec.second) | 
					
						
							|  |  |  | 	{				 | 
					
						
							|  |  |  | 		if(rec.first->name == name) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			temp_storage[x] = *rec.first; | 
					
						
							|  |  |  | 			rec.first = GPUmem.erase(rec.first); | 
					
						
							|  |  |  | 			sum += temp_storage[x].rows; | 
					
						
							|  |  |  | 			x++; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*gpunum = x; | 
					
						
							|  |  |  | 	temp.name = name; | 
					
						
							|  |  |  | 	temp.isrule = 1; | 
					
						
							|  |  |  | 	rec = equal_range(CPUmem.begin(), CPUmem.end(), temp, compareiteration); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while(rec.first != rec.second) | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	{				 | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		if(rec.first->name == name) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			temp_storage[x] = *rec.first; | 
					
						
							|  |  |  | 			rec.first = CPUmem.erase(rec.first); | 
					
						
							|  |  |  | 			sum += temp_storage[x].rows; | 
					
						
							|  |  |  | 			x++; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	i = CPUmem.insert(rec.first, temp); | 
					
						
							|  |  |  | 	*totalrows = sum; | 
					
						
							|  |  |  | 	*cpunum = x; | 
					
						
							|  |  |  | 	return i; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Removes the least recently used memory block from GPU memory, sending it to CPU memory if it's a rule result.  | 
					
						
							|  |  |  | If there are no used memory blocks in the GPU and we still don't have enough memory, the program exits with error*/ | 
					
						
							| 
									
										
										
										
											2013-10-17 00:44:24 +01:00
										 |  |  | void limpiar(const char s[], size_t sz) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	list<memnode>::iterator ini; | 
					
						
							|  |  |  | 	memnode temp; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	size_t free, total; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(GPUmem.size() == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemGetInfo(&free,&total); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		cerr << s << ": not enough GPU memory: have " << free << " of " << total << ", need " << sz << " bytes." << endl; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		exit(1); | 
					
						
							|  |  |  | 	}		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ini = GPUmem.begin(); | 
					
						
							|  |  |  | 	if(ini->isrule) | 
					
						
							|  |  |  | 	{	 | 
					
						
							|  |  |  | 		temp = *ini; | 
					
						
							|  |  |  | 		temp.dev_address = (int *)malloc(ini->size); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpyAsync(temp.dev_address, ini->dev_address, temp.size, hipMemcpyDeviceToHost); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		list<memnode>::iterator pos = lower_bound(CPUmem.begin(), CPUmem.end(), temp, compareiteration); | 
					
						
							|  |  |  | 		CPUmem.insert(pos, temp); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 	hipFree(ini->dev_address); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	GPUmem.erase(ini); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Allocs 'size' amount of bytes in GPU memory. If not enough memory is available, removes least recently used memory blocks until  | 
					
						
							|  |  |  | enough space is available*/ | 
					
						
							|  |  |  | void reservar(int **ptr, size_t size) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	size_t free, total; | 
					
						
							| 
									
										
										
										
											2013-10-12 01:11:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-12 12:46:01 +01:00
										 |  |  |         if (size == 0) {  | 
					
						
							|  |  |  |                 *ptr = NULL;  | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 	hipMemGetInfo(&free, &total); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	while(free < size) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		cout << "Se limpio memoria " << free << " " << total << endl; | 
					
						
							| 
									
										
										
										
											2013-10-17 00:44:24 +01:00
										 |  |  | 		limpiar("not enough memory", size); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemGetInfo(&free, &total); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 	while(hipMalloc(ptr, size) == hipErrorMemoryAllocation) | 
					
						
							| 
									
										
										
										
											2013-10-17 00:44:24 +01:00
										 |  |  | 		limpiar("Error in memory allocation", size); | 
					
						
							| 
									
										
										
										
											2013-10-12 12:46:01 +01:00
										 |  |  | 	if (! *ptr ) { | 
					
						
							|  |  |  | 	  size_t free, total; | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 	  hipMemGetInfo(      &free, &total	 ); | 
					
						
							| 
									
										
										
										
											2013-10-16 17:33:49 +01:00
										 |  |  | 	  cerr << "Could not allocate " << size << " bytes, only " << free << " avaliable from total of " << total << " !!!" << endl; | 
					
						
							|  |  |  | 	  cerr << "Exiting CUDA...." << endl; | 
					
						
							| 
									
										
										
										
											2013-10-12 12:46:01 +01:00
										 |  |  | 	  exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Creates a new entry in the GPU memory list*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | void registrar(int name, int num_columns, int *ptr, int rows, int itr, int rule) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memnode temp; | 
					
						
							|  |  |  | 	temp.name = name; | 
					
						
							|  |  |  | 	temp.dev_address = ptr; | 
					
						
							|  |  |  | 	temp.rows = rows; | 
					
						
							|  |  |  | 	temp.size = rows * num_columns * sizeof(int); | 
					
						
							|  |  |  | 	temp.iteration = itr; | 
					
						
							|  |  |  | 	temp.isrule = rule; | 
					
						
							|  |  |  | 	GPUmem.push_back(temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | void registrarcpu(int name, int num_columns, int *ptr, int rows, int itr, int rule) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memnode temp; | 
					
						
							|  |  |  | 	temp.name = name; | 
					
						
							|  |  |  | 	temp.dev_address = ptr; | 
					
						
							|  |  |  | 	temp.rows = rows; | 
					
						
							|  |  |  | 	temp.size = rows * num_columns * sizeof(int); | 
					
						
							|  |  |  | 	temp.iteration = itr; | 
					
						
							|  |  |  | 	temp.isrule = rule; | 
					
						
							|  |  |  | 	CPUmem.push_back(temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*Updates the information of an element in a list*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | template<class InputIterator> | 
					
						
							|  |  |  | void actualizar(int num_columns, int *ptr, int rows, InputIterator i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	i->dev_address = ptr; | 
					
						
							|  |  |  | 	i->rows = rows; | 
					
						
							|  |  |  | 	i->size = rows * num_columns * sizeof(int); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Count the total number of rows generated by rule 'name' in iteration 'iter'*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | int numrows(int name, int itr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int sum = 0; | 
					
						
							|  |  |  | 	memnode temp; | 
					
						
							|  |  |  | 	temp.iteration = itr; | 
					
						
							|  |  |  | 	pair<list<memnode>::iterator, list<memnode>::iterator> rec = equal_range(GPUmem.begin(), GPUmem.end(), temp, compareiteration); | 
					
						
							|  |  |  | 	while(rec.first != rec.second) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(rec.first->name == name) | 
					
						
							|  |  |  | 			sum += rec.first->rows; | 
					
						
							|  |  |  | 		rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rec = equal_range(CPUmem.begin(), CPUmem.end(), temp, compareiteration); | 
					
						
							|  |  |  | 	while(rec.first != rec.second) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(rec.first->name == name) | 
					
						
							|  |  |  | 			sum += rec.first->rows; | 
					
						
							|  |  |  | 		rec.first++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sum; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-12 01:11:21 +01:00
										 |  |  | 	extern "C" void * YAP_IntToAtom(int); | 
					
						
							|  |  |  | 	extern  "C" char * YAP_AtomName(void *); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Loads facts or rule results in GPU memory. If a fact is already in GPU memory, its pointer is simply returned. Otherwise,  | 
					
						
							|  |  |  | memory is reserved and the fact is loaded. Rule results are loaded based on the current iteration 'itr' and both GPU and  | 
					
						
							|  |  |  | CPU memories are searched for all instances of said results. The instances are combined into a single one in GPU memory.*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | int cargar(int name, int num_rows, int num_columns, int is_fact, int *address_host_table, int **ptr, int itr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int numgpu, numcpu, totalrows = 0; | 
					
						
							|  |  |  | 	int *temp, x; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	int size, itrant, inc = 0; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	list<memnode>::iterator i; | 
					
						
							|  |  |  | 	memnode fact; | 
					
						
							| 
									
										
										
										
											2013-10-12 01:11:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	if(is_fact) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		i = buscarhecho(GPUmem.begin(), GPUmem.end(), name); | 
					
						
							|  |  |  | 		if(i != GPUmem.end()) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			fact = *i; | 
					
						
							|  |  |  | 			GPUmem.erase(i); | 
					
						
							|  |  |  | 			fact.iteration = itr; | 
					
						
							|  |  |  | 			*ptr = fact.dev_address; | 
					
						
							|  |  |  | 			GPUmem.push_back(fact); | 
					
						
							|  |  |  | 			return fact.rows; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		size = num_rows * num_columns * sizeof(int); | 
					
						
							|  |  |  | 		reservar(&temp, size); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpyAsync(temp, address_host_table, size, hipMemcpyHostToDevice); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		registrar(name, num_columns, temp, num_rows, itr, 0); | 
					
						
							|  |  |  | 		*ptr = temp; | 
					
						
							|  |  |  | 		return num_rows; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(itr > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		itrant = itr - 1; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		i = buscarpornombre(name, itrant, &totalrows, &numgpu, &numcpu); | 
					
						
							|  |  |  | 		if((numgpu == 1) && (numcpu == 1)) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			actualizar(num_columns, temp_storage[0].dev_address, temp_storage[0].rows, i); | 
					
						
							|  |  |  | 			*ptr = temp_storage[0].dev_address; | 
					
						
							|  |  |  | 			return temp_storage[0].rows; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		size = totalrows * num_columns * sizeof(int); | 
					
						
							|  |  |  | 		reservar(&temp, size); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		for(x = 0; x < numgpu; x++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipMemcpyAsync(temp + inc, temp_storage[x].dev_address, temp_storage[x].size, hipMemcpyDeviceToDevice); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			inc += temp_storage[x].size / sizeof(int); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipFree(temp_storage[x].dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		for(; x < numcpu; x++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipMemcpyAsync(temp + inc, temp_storage[x].dev_address, temp_storage[x].size, hipMemcpyHostToDevice); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			inc += temp_storage[x].size / sizeof(int); | 
					
						
							|  |  |  | 			free(temp_storage[x].dev_address); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		actualizar(num_columns, temp, totalrows, i); | 
					
						
							|  |  |  | 		*ptr = temp; | 
					
						
							|  |  |  | 		return totalrows; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int cargarcpu(int name, int num_rows, int num_columns, int is_fact, int *address_host_table, int **ptr, int itr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int numgpu, numcpu, totalrows = 0; | 
					
						
							|  |  |  | 	int *temp, x; | 
					
						
							|  |  |  | 	int size, itrant, inc = 0; | 
					
						
							|  |  |  | 	list<memnode>::iterator i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(is_fact) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		*ptr = address_host_table; | 
					
						
							|  |  |  | 		return num_rows; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(itr > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		itrant = itr - 1; | 
					
						
							|  |  |  | 		i = buscarpornombrecpu(name, itrant, &totalrows, &numgpu, &numcpu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if((numgpu == 0) && (numcpu == 1)) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			actualizar(num_columns, temp_storage[0].dev_address, temp_storage[0].rows, i); | 
					
						
							|  |  |  | 			*ptr = temp_storage[0].dev_address; | 
					
						
							|  |  |  | 			return temp_storage[0].rows; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		size = totalrows * num_columns * sizeof(int); | 
					
						
							|  |  |  | 		temp = (int *)malloc(size); | 
					
						
							|  |  |  | 		for(x = 0; x < numgpu; x++) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipMemcpyAsync(temp + inc, temp_storage[x].dev_address, temp_storage[x].size, hipMemcpyDeviceToHost); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			inc += temp_storage[x].size / sizeof(int); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipFree(temp_storage[x].dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		for(; x < numcpu; x++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-06-30 14:33:32 +01:00
										 |  |  | 			memmove(temp + inc, temp_storage[x].dev_address, temp_storage[x].size); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			inc += temp_storage[x].size / sizeof(int); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 			free(temp_storage[x].dev_address); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		actualizar(num_columns, temp, totalrows, i); | 
					
						
							|  |  |  | 		*ptr = temp; | 
					
						
							|  |  |  | 		return totalrows; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Loads all results of rule 'name' from both GPU and CPU memories into the GPU*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | int cargafinal(int name, int cols, int **ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	int *temp, *ini, cont = 0, numg = 0, numc = 0; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	memnode bus; | 
					
						
							|  |  |  | 	bus.name = name; | 
					
						
							|  |  |  | 	GPUmem.sort(comparename); | 
					
						
							|  |  |  | 	CPUmem.sort(comparename); | 
					
						
							|  |  |  | 	list<memnode>::iterator endg = GPUmem.end(); | 
					
						
							|  |  |  | 	list<memnode>::iterator endc = CPUmem.end(); | 
					
						
							|  |  |  | 	list<memnode>::iterator pos = lower_bound(GPUmem.begin(), endg, bus, comparename); | 
					
						
							|  |  |  | 	list<memnode>::iterator gpu = pos; | 
					
						
							|  |  |  | 	while(pos != endg && pos->name == name) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		cont += pos->rows; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		numg++; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		pos++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	pos = lower_bound(CPUmem.begin(), endc, bus, comparename); | 
					
						
							|  |  |  | 	list<memnode>::iterator cpu = pos; | 
					
						
							|  |  |  | 	while(pos != endc && pos->name == name) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		cont += pos->rows; | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		numc++; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		pos++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	if(numg == 0 && numc == 0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if(numg == 1 && numc == 0)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		pos = gpu; | 
					
						
							|  |  |  | 		*ptr = pos->dev_address; | 
					
						
							|  |  |  | 		cont = pos->rows; | 
					
						
							|  |  |  | 		GPUmem.erase(pos); | 
					
						
							|  |  |  | 		#ifdef TUFFY | 
					
						
							|  |  |  | 		return -cont; | 
					
						
							|  |  |  | 		#else | 
					
						
							|  |  |  | 		return cont; | 
					
						
							|  |  |  | 		#endif | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(numg == 0 && numc == 1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		pos = cpu; | 
					
						
							|  |  |  | 		cont = pos->rows; | 
					
						
							|  |  |  | 		#ifdef TUFFY | 
					
						
							|  |  |  | 		reservar(&temp, pos->size); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpy(temp, pos->dev_address, pos->size, hipMemcpyHostToDevice); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		*ptr = temp; | 
					
						
							|  |  |  | 		#else | 
					
						
							|  |  |  | 		*ptr = pos->dev_address; | 
					
						
							|  |  |  | 		#endif | 
					
						
							|  |  |  | 		CPUmem.erase(pos); | 
					
						
							|  |  |  | 		return -cont; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reservar(&temp, cont * cols * sizeof(int)); | 
					
						
							|  |  |  | 	ini = temp; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	pos = gpu; | 
					
						
							|  |  |  | 	while(pos != endg && pos->name == name) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpy(temp, pos->dev_address, pos->size, hipMemcpyDeviceToDevice); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		temp += pos->size / sizeof(int); | 
					
						
							|  |  |  | 		pos++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	pos = cpu; | 
					
						
							|  |  |  | 	while(pos != endc && pos->name == name) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpy(temp, pos->dev_address, pos->size, hipMemcpyHostToDevice); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		temp += pos->size / sizeof(int); | 
					
						
							|  |  |  | 		pos++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*ptr = ini; | 
					
						
							|  |  |  | 	return cont; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Compares the results of the current iteration against the results of older iterations.  | 
					
						
							|  |  |  | Used to avoid infinite computations when the result is not a single fixed-point, but an  | 
					
						
							|  |  |  | orbit of points.*/ | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | bool generadas(int name, int filas, int cols, int itr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int r1, r2, x, fin; | 
					
						
							|  |  |  | 	int *dop1, *dop2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	r2 = numrows(name, itr); | 
					
						
							|  |  |  | 	if(itr < MAX_FIX_POINTS) | 
					
						
							|  |  |  | 		fin = itr; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		fin = MAX_FIX_POINTS; | 
					
						
							|  |  |  | 	for(x = 1; x <= fin; x++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		r1 = numrows(name, itr - x); | 
					
						
							|  |  |  | 		if(r1 == r2) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			r2 = cargar(name, filas, cols, 0, NULL, &dop2, itr + 1); | 
					
						
							|  |  |  | 			thrust::device_ptr<int> pt2 = thrust::device_pointer_cast(dop2); | 
					
						
							|  |  |  | 			r1 = cargar(name, filas, cols, 0, NULL, &dop1, itr - x + 1); | 
					
						
							|  |  |  | 			thrust::device_ptr<int> pt1 = thrust::device_pointer_cast(dop1); | 
					
						
							|  |  |  | 			if(thrust::equal(pt1, pt1 + r1, pt2) == true) | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mostrar_memoria() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	unsigned int x; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	list<memnode>::iterator i = GPUmem.begin(); | 
					
						
							|  |  |  | 	cout << "Memoria inicio GPU" << endl; | 
					
						
							|  |  |  | 	for(x = 0; x < GPUmem.size(); x++, i++) | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		cout << i->name << " " << i->iteration << " " << i->isrule << " " << i->rows << " " << i->size << endl; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	cout << "Memoria fin GPU" << endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mostrar_memcpu() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	unsigned int x; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	list<memnode>::iterator i = CPUmem.begin(); | 
					
						
							|  |  |  | 	cout << "Memoria inicio CPU" << endl; | 
					
						
							|  |  |  | 	for(x = 0; x < CPUmem.size(); x++, i++) | 
					
						
							|  |  |  | 		cout << i->name << " " << i->iteration << endl; | 
					
						
							|  |  |  | 	cout << "Memoria fin CPU" << endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Clear all rule results from both GPU and CPU memory*/ | 
					
						
							|  |  |  | void clear_memory() | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	list<memnode>::iterator ini; | 
					
						
							|  |  |  | 	list<memnode>::iterator fin; | 
					
						
							|  |  |  |        	ini = GPUmem.begin(); | 
					
						
							|  |  |  | 	fin = GPUmem.end(); | 
					
						
							|  |  |  | 	while(ini != fin) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		if(ini->isrule) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 			hipFree(ini->dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 			ini = GPUmem.erase(ini); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			ini++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ini = CPUmem.begin(); | 
					
						
							|  |  |  | 	fin = CPUmem.end(); | 
					
						
							|  |  |  | 	while(ini != fin) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		free(ini->dev_address); | 
					
						
							|  |  |  | 		ini++; | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	CPUmem.clear(); | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | /*Clear everything from both GPU and CPU memory*/ | 
					
						
							|  |  |  | void clear_memory_all() | 
					
						
							| 
									
										
										
										
											2013-10-07 12:20:00 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-09 11:23:45 +01:00
										 |  |  | 	list<memnode>::iterator ini; | 
					
						
							|  |  |  | 	list<memnode>::iterator fin; | 
					
						
							| 
									
										
										
										
											2013-10-12 01:11:21 +01:00
										 |  |  |        	ini = GPUmem.begin(); | 
					
						
							| 
									
										
										
										
											2013-10-09 11:23:45 +01:00
										 |  |  | 	fin = GPUmem.end(); | 
					
						
							|  |  |  | 	while(ini != fin) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipFree(ini->dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		ini++; | 
					
						
							| 
									
										
										
										
											2013-10-09 11:23:45 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	GPUmem.clear(); | 
					
						
							| 
									
										
										
										
											2013-10-09 11:23:45 +01:00
										 |  |  | 	ini = CPUmem.begin(); | 
					
						
							|  |  |  | 	fin = CPUmem.end(); | 
					
						
							|  |  |  | 	while(ini != fin) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		free(ini->dev_address); | 
					
						
							|  |  |  | 		ini++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	CPUmem.clear(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*Remove all instances of fact 'name' from both CPU and GPU memories*/ | 
					
						
							|  |  |  | void liberar(int name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	list<memnode>::iterator i; | 
					
						
							|  |  |  | 	memnode fact; | 
					
						
							|  |  |  | 	i = buscarhecho(GPUmem.begin(), GPUmem.end(), name); | 
					
						
							|  |  |  | 	if(i != GPUmem.end()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fact = *i; | 
					
						
							|  |  |  | 		GPUmem.erase(i); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipFree(fact.dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	i = buscarhecho(CPUmem.begin(), CPUmem.end(), name); | 
					
						
							|  |  |  | 	if(i != CPUmem.end()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fact = *i; | 
					
						
							|  |  |  | 		CPUmem.erase(i); | 
					
						
							|  |  |  | 		free(fact.dev_address); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*Add all rows in 'dop1' to the fact 'name' by creating a new array capable of holding both.*/ | 
					
						
							|  |  |  | void sumar(int name, int *dop1, int cols, int rows) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	list<memnode>::iterator i; | 
					
						
							|  |  |  | 	memnode fact; | 
					
						
							|  |  |  | 	i = buscarhecho(GPUmem.begin(), GPUmem.end(), name); | 
					
						
							|  |  |  | 	int *res, newrows, offset; | 
					
						
							|  |  |  | 	if(i != GPUmem.end()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fact = *i; | 
					
						
							|  |  |  | 		newrows = rows + fact.rows; | 
					
						
							|  |  |  | 		reservar(&res, newrows * cols * sizeof(int)); | 
					
						
							|  |  |  | 		offset = fact.rows * cols; | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpyAsync(res, fact.dev_address, offset * sizeof(int), hipMemcpyDeviceToDevice); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 		GPUmem.erase(i); | 
					
						
							|  |  |  | 		registrar(name, cols, res, newrows, 0, 0); | 
					
						
							| 
									
										
										
										
											2016-07-31 10:14:02 -05:00
										 |  |  | 		hipMemcpyAsync(res + offset, dop1, rows * cols * sizeof(int), hipMemcpyDeviceToDevice); | 
					
						
							|  |  |  | 		hipFree(fact.dev_address); | 
					
						
							| 
									
										
										
										
											2016-04-19 23:30:02 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |