#include "Graph.cuh"
#include "CudaHelper.cuh"
#include "VectorHelper.cuh"

namespace atspSolver
{
	Graph::Graph(int numberOfNodes) : numberOfNodes_(numberOfNodes), adjacencyMatrix_(new double[numberOfNodes*numberOfNodes])
	{
		Graph::generateGraph();
	}

	Graph::Graph(const double *adjacencyMatrix, int numberOfNodes) : numberOfNodes_(numberOfNodes), adjacencyMatrix_(new double[numberOfNodes*numberOfNodes])
	{
		memcpy(this->adjacencyMatrix_, adjacencyMatrix, sizeof(double) * numberOfNodes * numberOfNodes);
	}

	Graph::~Graph()
	{
		delete[] adjacencyMatrix_;
	}

	void Graph::copyElementsFromGraph(const Graph& graph)
	{
		double *devAdjacencyMatrixSrc, *devAdjacencyMatrixDst;
		unsigned int totalBytes = sizeof(double) * numberOfNodes_ * numberOfNodes_;

		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrixSrc, totalBytes));
		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrixDst, totalBytes));
		CUDA_ERR_CHECK(cudaMemcpy((void *)devAdjacencyMatrixSrc, (const void *)graph.adjacencyMatrix_, totalBytes, cudaMemcpyHostToDevice));
		d_copyVectorElements << <blocksPerGrid, threadsPerBlock >> > (devAdjacencyMatrixDst, devAdjacencyMatrixSrc, numberOfNodes_ * numberOfNodes_);
		CUDA_ERR_CHECK(cudaMemcpy(adjacencyMatrix_, devAdjacencyMatrixDst, totalBytes, cudaMemcpyDeviceToHost));

		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrixSrc));
		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrixDst));
	}

	Graph::Graph(const Graph& graph)
	{
		adjacencyMatrix_ = new double[graph.numberOfNodes_ * graph.numberOfNodes_];
		numberOfNodes_ = graph.numberOfNodes_;

		copyElementsFromGraph(graph);
	}

	Graph& Graph::operator=(const Graph& graph)
	{
		double *origAdjacencyMatrix = adjacencyMatrix_;
		adjacencyMatrix_ = new double[graph.numberOfNodes_ * graph.numberOfNodes_];
		numberOfNodes_ = graph.numberOfNodes_;

		copyElementsFromGraph(graph);

		delete[] origAdjacencyMatrix;

		return *this;
	}

	double Graph::operator()(int row, int col) const
	{
		int index = col + row * numberOfNodes_;
		return this->adjacencyMatrix_[index];
	}

	double Graph::operator[](int index) const
	{
		return this->adjacencyMatrix_[index];
	}

	Graph Graph::operator+(const Graph& graph) const
	{
		if (numberOfNodes_ != graph.numberOfNodes_)
		{
			throw;
		}
		double *devAdjacencyMatrix1, *devAdjacencyMatrix2, *devAdjacencyMatrixDst;
		unsigned int totalBytes = sizeof(double) * numberOfNodes_ * numberOfNodes_;

		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrix1, totalBytes));
		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrix2, totalBytes));
		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrixDst, totalBytes));
		CUDA_ERR_CHECK(cudaMemcpy((void *)devAdjacencyMatrix1, (const void *)graph.adjacencyMatrix_, totalBytes, cudaMemcpyHostToDevice));
		CUDA_ERR_CHECK(cudaMemcpy((void *)devAdjacencyMatrix2, (const void *)adjacencyMatrix_, totalBytes, cudaMemcpyHostToDevice));

		cudaEvent_t start, stop;
		cudaEventCreate(&start);
		cudaEventCreate(&stop);
		cudaEventRecord(start, 0);
		
		// gpu work
		d_sumVectorElements << <blocksPerGrid, threadsPerBlock >> > (devAdjacencyMatrix1, devAdjacencyMatrix2, devAdjacencyMatrixDst, numberOfNodes_ * numberOfNodes_);
		
		cudaEventRecord(stop, 0);
		cudaEventSynchronize(stop);
		float elapsedTime;
		cudaEventElapsedTime(&elapsedTime, start, stop);
		
		std::cout << std::endl;
		std::cout << "---> Duration in Graph addition: " << elapsedTime << " ms." << " <---" << std::endl;
		std::cout << std::endl;

		double *result = new double[numberOfNodes_ * numberOfNodes_];
		CUDA_ERR_CHECK(cudaMemcpy((void *)result, (const void *)devAdjacencyMatrixDst, totalBytes, cudaMemcpyDeviceToHost));

		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrix1));
		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrix2));
		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrixDst));

		return Graph((const double *)result, numberOfNodes_);
	}

	void Graph::generateGraph()
	{
		double *devAdjacencyMatrix;
		unsigned int totalBytes = sizeof(double) * numberOfNodes_ * numberOfNodes_;

		CUDA_ERR_CHECK(cudaMalloc((void**)&devAdjacencyMatrix, totalBytes));
		cudaEvent_t start, stop;
		cudaEventCreate(&start);
		cudaEventCreate(&stop);
		cudaEventRecord(start, 0);

		// gpu work
		d_fillVectorRandomly << <blocksPerGrid, threadsPerBlock >> > (devAdjacencyMatrix, numberOfNodes_ * numberOfNodes_);

		cudaEventRecord(stop, 0);
		cudaEventSynchronize(stop);
		float elapsedTime;
		cudaEventElapsedTime(&elapsedTime, start, stop);

		std::cout << std::endl;
		std::cout << "---> Duration in Graph generation with random numbers: " << elapsedTime << " ms." << " <---" << std::endl;

		CUDA_ERR_CHECK(cudaMemcpy(adjacencyMatrix_, devAdjacencyMatrix, totalBytes, cudaMemcpyDeviceToHost));
		//displayMatrix((const double *)adjacencyMatrix, numberOfNodes, numberOfNodes);

		CUDA_ERR_CHECK(cudaFree(devAdjacencyMatrix));
	}

	int Graph::getNumberOfNodes() const
	{
		return numberOfNodes_;
	}

	void Graph::display() const
	{
		displayMatrix((const double *)adjacencyMatrix_, numberOfNodes_, numberOfNodes_);
	}
}
	.file	"tmpxft_002c6f61_00000000-6_Graph.cudafe1.cpp"
	.text
#APP
	.globl _ZSt21ios_base_library_initv

#NO_APP
	.type	_ZL26__cudaUnregisterBinaryUtilv, @function
_ZL26__cudaUnregisterBinaryUtilv:
.LFB3660:
	.cfi_startproc
	endbr64
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	jmp	__cudaUnregisterFatBinary@PLT
	.cfi_endproc
.LFE3660:
	.size	_ZL26__cudaUnregisterBinaryUtilv, .-_ZL26__cudaUnregisterBinaryUtilv
	.align 2
	.type	_ZNSolsEPFRSoS_E.isra.0, @function
_ZNSolsEPFRSoS_E.isra.0:
.LFB4312:
	.cfi_startproc
	jmp	*%rsi
	.cfi_endproc
.LFE4312:
	.size	_ZNSolsEPFRSoS_E.isra.0, .-_ZNSolsEPFRSoS_E.isra.0
	.align 2
	.globl	_ZN10atspSolver5GraphC2EPKdi
	.type	_ZN10atspSolver5GraphC2EPKdi, @function
_ZN10atspSolver5GraphC2EPKdi:
.LFB3642:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	movq	%rdi, %r13
	pushq	%r12
	.cfi_def_cfa_offset 24
	.cfi_offset 12, -24
	movq	%rdx, %r12
	pushq	%rbp
	.cfi_def_cfa_offset 32
	.cfi_offset 6, -32
	pushq	%rbx
	.cfi_def_cfa_offset 40
	.cfi_offset 3, -40
	movslq	%ecx, %rbx
	movl	%ebx, %ebp
	pushq	%rax
	.cfi_def_cfa_offset 48
	movq	(%rsi), %rax
	imull	%ebx, %ebp
	movl	%ebx, 8(%rdi)
	movq	%rax, (%rdi)
	imulq	%rbx, %rbx
	movslq	%ebp, %rbp
	salq	$3, %rbp
	movq	%rbp, %rdi
	call	_Znam@PLT
	leaq	0(,%rbx,8), %rdx
	movq	%rbp, %rcx
	movq	%r12, %rsi
	movq	%rax, 16(%r13)
	movq	%rax, %rdi
	popq	%r8
	.cfi_def_cfa_offset 40
	popq	%rbx
	.cfi_def_cfa_offset 32
	popq	%rbp
	.cfi_def_cfa_offset 24
	popq	%r12
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	jmp	__memcpy_chk@PLT
	.cfi_endproc
.LFE3642:
	.size	_ZN10atspSolver5GraphC2EPKdi, .-_ZN10atspSolver5GraphC2EPKdi
	.align 2
	.globl	_ZN10atspSolver5GraphC1EPKdi
	.type	_ZN10atspSolver5GraphC1EPKdi, @function
_ZN10atspSolver5GraphC1EPKdi:
.LFB3643:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	leaq	24+_ZTVN10atspSolver5GraphE(%rip), %rax
	movq	%rdi, %r13
	pushq	%rbp
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	movslq	%edx, %rbx
	movl	%ebx, %ebp
	imull	%ebx, %ebp
	subq	$16, %rsp
	.cfi_def_cfa_offset 48
	movl	%ebx, 8(%rdi)
	imulq	%rbx, %rbx
	movq	%rax, (%rdi)
	movslq	%ebp, %rbp
	movq	%rsi, 8(%rsp)
	salq	$3, %rbp
	movq	%rbp, %rdi
	call	_Znam@PLT
	movq	8(%rsp), %rsi
	leaq	0(,%rbx,8), %rdx
	movq	%rbp, %rcx
	movq	%rax, 16(%r13)
	addq	$16, %rsp
	.cfi_def_cfa_offset 32
	movq	%rax, %rdi
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	jmp	__memcpy_chk@PLT
	.cfi_endproc
.LFE3643:
	.size	_ZN10atspSolver5GraphC1EPKdi, .-_ZN10atspSolver5GraphC1EPKdi
	.align 2
	.globl	_ZN10atspSolver5GraphD2Ev
	.type	_ZN10atspSolver5GraphD2Ev, @function
_ZN10atspSolver5GraphD2Ev:
.LFB3645:
	.cfi_startproc
	endbr64
	movq	(%rsi), %rax
	movq	%rax, (%rdi)
	movq	16(%rdi), %rdi
	testq	%rdi, %rdi
	je	.L7
	jmp	_ZdaPv@PLT
.L7:
	ret
	.cfi_endproc
.LFE3645:
	.size	_ZN10atspSolver5GraphD2Ev, .-_ZN10atspSolver5GraphD2Ev
	.align 2
	.globl	_ZN10atspSolver5GraphD1Ev
	.type	_ZN10atspSolver5GraphD1Ev, @function
_ZN10atspSolver5GraphD1Ev:
.LFB3646:
	.cfi_startproc
	endbr64
	leaq	24+_ZTVN10atspSolver5GraphE(%rip), %rax
	movq	%rax, (%rdi)
	movq	16(%rdi), %rdi
	testq	%rdi, %rdi
	je	.L10
	jmp	_ZdaPv@PLT
.L10:
	ret
	.cfi_endproc
.LFE3646:
	.size	_ZN10atspSolver5GraphD1Ev, .-_ZN10atspSolver5GraphD1Ev
	.align 2
	.globl	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_
	.type	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_, @function
_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_:
.LFB3647:
	.cfi_startproc
	endbr64
	pushq	%r12
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	movq	%rsi, %r12
	pushq	%rbp
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	movq	%rdi, %rbx
	subq	$48, %rsp
	.cfi_def_cfa_offset 80
	movq	%fs:40, %rax
	movq	%rax, 40(%rsp)
	movl	8(%rdi), %eax
	movq	%rsp, %rdi
	imull	%eax, %eax
	leal	0(,%rax,8), %ebp
	movq	%rbp, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	%rbp, %rsi
	leaq	8(%rsp), %rdi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	16(%r12), %rsi
	movq	(%rsp), %rdi
	movq	%rbp, %rdx
	movl	$1, %ecx
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movl	$33554433, %edi
	xorl	%r9d, %r9d
	xorl	%r8d, %r8d
	salq	$7, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdi, %rdx
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L13
	movl	8(%rbx), %edx
	movq	(%rsp), %rsi
	movq	8(%rsp), %rdi
	imull	%edx, %edx
	call	_ZN10atspSolver20d_copyVectorElementsEPdS0_i@PLT
.L13:
	movq	8(%rsp), %rsi
	movq	16(%rbx), %rdi
	movl	$2, %ecx
	movq	%rbp, %rdx
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	8(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	40(%rsp), %rax
	subq	%fs:40, %rax
	je	.L14
	call	__stack_chk_fail@PLT
.L14:
	addq	$48, %rsp
	.cfi_def_cfa_offset 32
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE3647:
	.size	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_, .-_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_
	.align 2
	.globl	_ZN10atspSolver5GraphC2ERKS0_
	.type	_ZN10atspSolver5GraphC2ERKS0_, @function
_ZN10atspSolver5GraphC2ERKS0_:
.LFB3649:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rdx, %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	movq	%rdi, %rbx
	pushq	%rax
	.cfi_def_cfa_offset 32
	movq	(%rsi), %rax
	movq	%rax, (%rdi)
	movl	8(%rdx), %edi
	imull	%edi, %edi
	movslq	%edi, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	movq	%rax, 16(%rbx)
	movl	8(%rbp), %eax
	movl	%eax, 8(%rbx)
	popq	%rdx
	.cfi_def_cfa_offset 24
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	jmp	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_
	.cfi_endproc
.LFE3649:
	.size	_ZN10atspSolver5GraphC2ERKS0_, .-_ZN10atspSolver5GraphC2ERKS0_
	.align 2
	.globl	_ZN10atspSolver5GraphC1ERKS0_
	.type	_ZN10atspSolver5GraphC1ERKS0_, @function
_ZN10atspSolver5GraphC1ERKS0_:
.LFB3650:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	leaq	24+_ZTVN10atspSolver5GraphE(%rip), %rax
	movq	%rdi, %rbx
	subq	$16, %rsp
	.cfi_def_cfa_offset 32
	movq	%rax, (%rdi)
	movl	8(%rsi), %edi
	movq	%rsi, 8(%rsp)
	imull	%edi, %edi
	movslq	%edi, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	8(%rsp), %rsi
	movq	%rbx, %rdi
	movq	%rax, 16(%rbx)
	movl	8(%rsi), %eax
	movl	%eax, 8(%rbx)
	addq	$16, %rsp
	.cfi_def_cfa_offset 16
	popq	%rbx
	.cfi_def_cfa_offset 8
	jmp	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_
	.cfi_endproc
.LFE3650:
	.size	_ZN10atspSolver5GraphC1ERKS0_, .-_ZN10atspSolver5GraphC1ERKS0_
	.align 2
	.globl	_ZN10atspSolver5GraphaSERKS0_
	.type	_ZN10atspSolver5GraphaSERKS0_, @function
_ZN10atspSolver5GraphaSERKS0_:
.LFB3651:
	.cfi_startproc
	endbr64
	pushq	%r12
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	movq	%rdi, %rbx
	subq	$24, %rsp
	.cfi_def_cfa_offset 48
	movq	16(%rdi), %r12
	movl	8(%rsi), %edi
	movq	%rsi, 8(%rsp)
	imull	%edi, %edi
	movslq	%edi, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	8(%rsp), %rsi
	movq	%rbx, %rdi
	movq	%rax, 16(%rbx)
	movl	8(%rsi), %eax
	movl	%eax, 8(%rbx)
	call	_ZN10atspSolver5Graph21copyElementsFromGraphERKS0_
	testq	%r12, %r12
	je	.L21
	movq	%r12, %rdi
	call	_ZdaPv@PLT
.L21:
	addq	$24, %rsp
	.cfi_def_cfa_offset 24
	movq	%rbx, %rax
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE3651:
	.size	_ZN10atspSolver5GraphaSERKS0_, .-_ZN10atspSolver5GraphaSERKS0_
	.align 2
	.globl	_ZNK10atspSolver5GraphclEii
	.type	_ZNK10atspSolver5GraphclEii, @function
_ZNK10atspSolver5GraphclEii:
.LFB3652:
	.cfi_startproc
	endbr64
	imull	8(%rdi), %esi
	movq	16(%rdi), %rax
	addl	%edx, %esi
	movslq	%esi, %rsi
	movsd	(%rax,%rsi,8), %xmm0
	ret
	.cfi_endproc
.LFE3652:
	.size	_ZNK10atspSolver5GraphclEii, .-_ZNK10atspSolver5GraphclEii
	.align 2
	.globl	_ZNK10atspSolver5GraphixEi
	.type	_ZNK10atspSolver5GraphixEi, @function
_ZNK10atspSolver5GraphixEi:
.LFB3653:
	.cfi_startproc
	endbr64
	movq	16(%rdi), %rax
	movslq	%esi, %rsi
	movsd	(%rax,%rsi,8), %xmm0
	ret
	.cfi_endproc
.LFE3653:
	.size	_ZNK10atspSolver5GraphixEi, .-_ZNK10atspSolver5GraphixEi
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"---> Duration in Graph addition: "
.LC1:
	.string	" ms."
.LC2:
	.string	" <---"
	.text
	.align 2
	.globl	_ZNK10atspSolver5GraphplERKS0_
	.type	_ZNK10atspSolver5GraphplERKS0_, @function
_ZNK10atspSolver5GraphplERKS0_:
.LFB3654:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	pushq	%r12
	.cfi_def_cfa_offset 24
	.cfi_offset 12, -24
	pushq	%rbp
	.cfi_def_cfa_offset 32
	.cfi_offset 6, -32
	pushq	%rbx
	.cfi_def_cfa_offset 40
	.cfi_offset 3, -40
	subq	$88, %rsp
	.cfi_def_cfa_offset 128
	movq	%fs:40, %rax
	movq	%rax, 72(%rsp)
	movl	8(%rsi), %eax
	cmpl	8(%rdx), %eax
	je	.L29
	movq	72(%rsp), %rax
	subq	%fs:40, %rax
	jne	.L34
	call	__cxa_rethrow@PLT
.L29:
	imull	%eax, %eax
	movq	%rsi, %rbx
	movq	%rdi, %r12
	movq	%rdx, %r13
	leaq	8(%rsp), %rdi
	leal	0(,%rax,8), %ebp
	movq	%rbp, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	%rbp, %rsi
	leaq	16(%rsp), %rdi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	%rbp, %rsi
	leaq	24(%rsp), %rdi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	16(%r13), %rsi
	movq	8(%rsp), %rdi
	movq	%rbp, %rdx
	movl	$1, %ecx
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	16(%rbx), %rsi
	movq	16(%rsp), %rdi
	movq	%rbp, %rdx
	movl	$1, %ecx
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	leaq	32(%rsp), %rdi
	call	cudaEventCreate@PLT
	leaq	40(%rsp), %rdi
	call	cudaEventCreate@PLT
	movq	32(%rsp), %rdi
	xorl	%esi, %esi
	call	cudaEventRecord@PLT
	movl	$33554433, %edi
	xorl	%r9d, %r9d
	xorl	%r8d, %r8d
	salq	$7, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movl	$1, 68(%rsp)
	movq	%rdi, %rdx
	movq	%rdi, 60(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L31
	movl	8(%rbx), %ecx
	movq	24(%rsp), %rdx
	movq	16(%rsp), %rsi
	movq	8(%rsp), %rdi
	imull	%ecx, %ecx
	call	_ZN10atspSolver19d_sumVectorElementsEPdS0_S0_i@PLT
.L31:
	movq	40(%rsp), %rdi
	xorl	%esi, %esi
	leaq	_ZSt4cout(%rip), %r13
	call	cudaEventRecord@PLT
	movq	40(%rsp), %rdi
	call	cudaEventSynchronize@PLT
	movq	40(%rsp), %rdx
	movq	32(%rsp), %rsi
	leaq	60(%rsp), %rdi
	call	cudaEventElapsedTime@PLT
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	movq	%r13, %rdi
	call	_ZNSolsEPFRSoS_E.isra.0
	leaq	.LC0(%rip), %rsi
	movq	%r13, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	cvtss2sd	60(%rsp), %xmm0
	movq	%rax, %rdi
	call	_ZNSo9_M_insertIdEERSoT_@PLT
	leaq	.LC1(%rip), %rsi
	movq	%rax, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	leaq	.LC2(%rip), %rsi
	movq	%rax, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	movq	%rax, %rdi
	call	_ZNSolsEPFRSoS_E.isra.0
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	movq	%r13, %rdi
	call	_ZNSolsEPFRSoS_E.isra.0
	movl	8(%rbx), %edi
	imull	%edi, %edi
	movslq	%edi, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	24(%rsp), %rsi
	movq	%rbp, %rdx
	movl	$2, %ecx
	movq	%rax, %rdi
	movq	%rax, %r13
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	8(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	16(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	24(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movl	8(%rbx), %edx
	movq	%r13, %rsi
	movq	%r12, %rdi
	call	_ZN10atspSolver5GraphC1EPKdi
	movq	72(%rsp), %rax
	subq	%fs:40, %rax
	je	.L32
.L34:
	call	__stack_chk_fail@PLT
.L32:
	addq	$88, %rsp
	.cfi_def_cfa_offset 40
	movq	%r12, %rax
	popq	%rbx
	.cfi_def_cfa_offset 32
	popq	%rbp
	.cfi_def_cfa_offset 24
	popq	%r12
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE3654:
	.size	_ZNK10atspSolver5GraphplERKS0_, .-_ZNK10atspSolver5GraphplERKS0_
	.section	.rodata.str1.1
.LC3:
	.string	"---> Duration in Graph generation with random numbers: "
	.text
	.align 2
	.globl	_ZN10atspSolver5Graph13generateGraphEv
	.type	_ZN10atspSolver5Graph13generateGraphEv, @function
_ZN10atspSolver5Graph13generateGraphEv:
.LFB3655:
	.cfi_startproc
	endbr64
	pushq	%r12
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	pushq	%rbp
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	movq	%rdi, %rbx
	subq	$64, %rsp
	.cfi_def_cfa_offset 96
	movq	%fs:40, %rax
	movq	%rax, 56(%rsp)
	movl	8(%rdi), %eax
	leaq	8(%rsp), %rdi
	imull	%eax, %eax
	leal	0(,%rax,8), %ebp
	movq	%rbp, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	leaq	16(%rsp), %rdi
	call	cudaEventCreate@PLT
	leaq	24(%rsp), %rdi
	call	cudaEventCreate@PLT
	movq	16(%rsp), %rdi
	xorl	%esi, %esi
	call	cudaEventRecord@PLT
	movl	$33554433, %edi
	xorl	%r9d, %r9d
	xorl	%r8d, %r8d
	salq	$7, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movl	$1, 52(%rsp)
	movq	%rdi, %rdx
	movq	%rdi, 44(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L36
	movl	8(%rbx), %esi
	movq	8(%rsp), %rdi
	imull	%esi, %esi
	call	_ZN10atspSolver20d_fillVectorRandomlyEPdi@PLT
.L36:
	movq	24(%rsp), %rdi
	xorl	%esi, %esi
	leaq	_ZSt4cout(%rip), %r12
	call	cudaEventRecord@PLT
	movq	24(%rsp), %rdi
	call	cudaEventSynchronize@PLT
	movq	24(%rsp), %rdx
	movq	16(%rsp), %rsi
	leaq	44(%rsp), %rdi
	call	cudaEventElapsedTime@PLT
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	movq	%r12, %rdi
	call	_ZNSolsEPFRSoS_E.isra.0
	leaq	.LC3(%rip), %rsi
	movq	%r12, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	cvtss2sd	44(%rsp), %xmm0
	movq	%rax, %rdi
	call	_ZNSo9_M_insertIdEERSoT_@PLT
	leaq	.LC1(%rip), %rsi
	movq	%rax, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	leaq	.LC2(%rip), %rsi
	movq	%rax, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	movq	%rax, %rdi
	call	_ZNSolsEPFRSoS_E.isra.0
	movq	8(%rsp), %rsi
	movq	16(%rbx), %rdi
	movq	%rbp, %rdx
	movl	$2, %ecx
	call	cudaMemcpy@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	8(%rsp), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	call	_Z15checkCudaErrors9cudaError@PLT
	movq	56(%rsp), %rax
	subq	%fs:40, %rax
	je	.L37
	call	__stack_chk_fail@PLT
.L37:
	addq	$64, %rsp
	.cfi_def_cfa_offset 32
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE3655:
	.size	_ZN10atspSolver5Graph13generateGraphEv, .-_ZN10atspSolver5Graph13generateGraphEv
	.align 2
	.globl	_ZN10atspSolver5GraphC1Ei
	.type	_ZN10atspSolver5GraphC1Ei, @function
_ZN10atspSolver5GraphC1Ei:
.LFB3640:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	leaq	24+_ZTVN10atspSolver5GraphE(%rip), %rax
	movq	%rdi, %rbx
	movl	%esi, 8(%rdi)
	imull	%esi, %esi
	movq	%rax, (%rdi)
	movslq	%esi, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	%rbx, %rdi
	movq	%rax, 16(%rbx)
	popq	%rbx
	.cfi_def_cfa_offset 8
	jmp	_ZN10atspSolver5Graph13generateGraphEv
	.cfi_endproc
.LFE3640:
	.size	_ZN10atspSolver5GraphC1Ei, .-_ZN10atspSolver5GraphC1Ei
	.align 2
	.globl	_ZN10atspSolver5GraphC2Ei
	.type	_ZN10atspSolver5GraphC2Ei, @function
_ZN10atspSolver5GraphC2Ei:
.LFB3639:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	movq	(%rsi), %rax
	movq	%rdi, %rbx
	movl	%edx, 8(%rdi)
	imull	%edx, %edx
	movq	%rax, (%rdi)
	movslq	%edx, %rdi
	salq	$3, %rdi
	call	_Znam@PLT
	movq	%rbx, %rdi
	movq	%rax, 16(%rbx)
	popq	%rbx
	.cfi_def_cfa_offset 8
	jmp	_ZN10atspSolver5Graph13generateGraphEv
	.cfi_endproc
.LFE3639:
	.size	_ZN10atspSolver5GraphC2Ei, .-_ZN10atspSolver5GraphC2Ei
	.align 2
	.globl	_ZNK10atspSolver5Graph16getNumberOfNodesEv
	.type	_ZNK10atspSolver5Graph16getNumberOfNodesEv, @function
_ZNK10atspSolver5Graph16getNumberOfNodesEv:
.LFB3656:
	.cfi_startproc
	endbr64
	movl	8(%rdi), %eax
	ret
	.cfi_endproc
.LFE3656:
	.size	_ZNK10atspSolver5Graph16getNumberOfNodesEv, .-_ZNK10atspSolver5Graph16getNumberOfNodesEv
	.align 2
	.globl	_ZNK10atspSolver5Graph7displayEv
	.type	_ZNK10atspSolver5Graph7displayEv, @function
_ZNK10atspSolver5Graph7displayEv:
.LFB3657:
	.cfi_startproc
	endbr64
	movl	8(%rdi), %esi
	movq	16(%rdi), %rdi
	movl	%esi, %edx
	jmp	_ZN10atspSolver13displayMatrixEPKdii@PLT
	.cfi_endproc
.LFE3657:
	.size	_ZNK10atspSolver5Graph7displayEv, .-_ZNK10atspSolver5Graph7displayEv
	.section	.text.startup,"ax",@progbits
	.type	_ZL24__sti____cudaRegisterAllv, @function
_ZL24__sti____cudaRegisterAllv:
.LFB3683:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	leaq	_ZL15__fatDeviceText(%rip), %rdi
	call	__cudaRegisterFatBinary@PLT
	movq	%rax, %rdi
	movq	%rax, _ZL20__cudaFatCubinHandle(%rip)
	call	__cudaRegisterFatBinaryEnd@PLT
	leaq	_ZL26__cudaUnregisterBinaryUtilv(%rip), %rdi
	popq	%rdx
	.cfi_def_cfa_offset 8
	jmp	atexit@PLT
	.cfi_endproc
.LFE3683:
	.size	_ZL24__sti____cudaRegisterAllv, .-_ZL24__sti____cudaRegisterAllv
	.section	.init_array,"aw"
	.align 8
	.quad	_ZL24__sti____cudaRegisterAllv
	.weak	_ZTSN10atspSolver5FinalE
	.section	.rodata._ZTSN10atspSolver5FinalE,"aG",@progbits,_ZTSN10atspSolver5FinalE,comdat
	.align 16
	.type	_ZTSN10atspSolver5FinalE, @object
	.size	_ZTSN10atspSolver5FinalE, 21
_ZTSN10atspSolver5FinalE:
	.string	"N10atspSolver5FinalE"
	.weak	_ZTIN10atspSolver5FinalE
	.section	.data.rel.ro._ZTIN10atspSolver5FinalE,"awG",@progbits,_ZTIN10atspSolver5FinalE,comdat
	.align 8
	.type	_ZTIN10atspSolver5FinalE, @object
	.size	_ZTIN10atspSolver5FinalE, 16
_ZTIN10atspSolver5FinalE:
	.quad	_ZTVN10__cxxabiv117__class_type_infoE+16
	.quad	_ZTSN10atspSolver5FinalE
	.weak	_ZTSN10atspSolver5GraphE
	.section	.rodata._ZTSN10atspSolver5GraphE,"aG",@progbits,_ZTSN10atspSolver5GraphE,comdat
	.align 16
	.type	_ZTSN10atspSolver5GraphE, @object
	.size	_ZTSN10atspSolver5GraphE, 21
_ZTSN10atspSolver5GraphE:
	.string	"N10atspSolver5GraphE"
	.weak	_ZTIN10atspSolver5GraphE
	.section	.data.rel.ro._ZTIN10atspSolver5GraphE,"awG",@progbits,_ZTIN10atspSolver5GraphE,comdat
	.align 8
	.type	_ZTIN10atspSolver5GraphE, @object
	.size	_ZTIN10atspSolver5GraphE, 40
_ZTIN10atspSolver5GraphE:
	.quad	_ZTVN10__cxxabiv121__vmi_class_type_infoE+16
	.quad	_ZTSN10atspSolver5GraphE
	.long	0
	.long	1
	.quad	_ZTIN10atspSolver5FinalE
	.quad	-6143
	.weak	_ZTTN10atspSolver5GraphE
	.section	.data.rel.ro.local._ZTTN10atspSolver5GraphE,"awG",@progbits,_ZTVN10atspSolver5GraphE,comdat
	.align 8
	.type	_ZTTN10atspSolver5GraphE, @object
	.size	_ZTTN10atspSolver5GraphE, 8
_ZTTN10atspSolver5GraphE:
	.quad	_ZTVN10atspSolver5GraphE+24
	.weak	_ZTVN10atspSolver5GraphE
	.section	.data.rel.ro.local._ZTVN10atspSolver5GraphE,"awG",@progbits,_ZTVN10atspSolver5GraphE,comdat
	.align 8
	.type	_ZTVN10atspSolver5GraphE, @object
	.size	_ZTVN10atspSolver5GraphE, 24
_ZTVN10atspSolver5GraphE:
	.quad	0
	.quad	0
	.quad	_ZTIN10atspSolver5GraphE
	.section	.nvFatBinSegment,"aw"
	.align 8
	.type	_ZL15__fatDeviceText, @object
	.size	_ZL15__fatDeviceText, 24
_ZL15__fatDeviceText:
	.long	1180844977
	.long	1
	.quad	fatbinData
	.quad	0
	.local	_ZL20__cudaFatCubinHandle
	.comm	_ZL20__cudaFatCubinHandle,8,8
	.ident	"GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	1f - 0f
	.long	4f - 1f
	.long	5
0:
	.string	"GNU"
1:
	.align 8
	.long	0xc0000002
	.long	3f - 2f
2:
	.long	0x3
3:
	.align 8
4:

#pragma once
#include <hip/hip_runtime.h>


namespace atspSolver
{
	// Graph implementation with adjacency matrix
	class Graph;
	// to make Graph class final
	class Final
	{
	private:
		Final() {};
		friend class Graph;
	};

	class Graph : virtual Final
	{
	public:
		Graph(int numberOfNodes = 1);
		Graph(const double *adjacencyMatrix, int numberOfNodes = 1);
		~Graph();
		Graph(const Graph& graph);
		Graph& operator=(const Graph& graph);
		double operator()(int row, int col) const;
		double operator[](int index) const;
		Graph operator+(const Graph& graph) const;
		int getNumberOfNodes() const;
		void display() const;
	private:
		int numberOfNodes_;
		double* adjacencyMatrix_;
		void generateGraph();
		void copyElementsFromGraph(const Graph& graph);
	};
}
	.text
	.file	"Graph.hip"
	.type	__hip_cuid_,@object             # @__hip_cuid_
	.bss
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               # 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_

	.text
	.p2alignl 7, 3214868480
	.fill 96, 4, 3214868480
	.type	__hip_cuid_,@object             ; @__hip_cuid_
	.section	.bss,"aw",@nobits
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               ; 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_
	.amdgcn_target "amdgcn-amd-amdhsa--gfx1100"
	.amdgpu_metadata
---
amdhsa.kernels:  []
amdhsa.target:   amdgcn-amd-amdhsa--gfx1100
amdhsa.version:
  - 1
  - 2
...

	.end_amdgpu_metadata
