<기본설치>

1.쿠다설치

2.MeCab설치

3.dataset준비 : MNIST, Cifar-10, TanakaCorpusUTF-8, MeCab

<관련설정>

1.VS, 프로젝트-빌드종속성-사용자지정빌드-CUDA활성화

2.VS, 프로젝트-속성-VC++디렉터리-포함디렉터리-~~~\\CUDA\\v12.3\\include추가

3.

[2] 병렬프로그래밍 & 행렬연산 class cuMat

float* mDevice = NULL; //GPU &Memory

cudaMalloc((void**)&mDevice, rows * cols * sizeof(*mDevice)); //메모리할당

ㄴvoid포인터타입은 모든 자료형의 어드레스를 담을 수 있는 포인터타입

ㄴ(void**)이중포인터 강제 캐스팅, 보통 메모리할당/재할당등의 이유로 '하드웨어의 인덱스인 주소를 담은 포인터'의 물리적 메모리 위치를 바꾸기위해 다시 포인터에 담아 쓰는 타입

ㄴ타입이 이중포인터이므로 인자는 &포인터가 사용되어야함

ㄴ인자에 &어드레스가 쓰이는 경우, 실질적으로 해당 어드레스쪽으로 return을 하게됨

ㄴ*mDevice : 포인터역참조로 해당 주소의 값을 반환, 이 경우는 자료형 사이즈 측정목적

cublasCreate(&cudaHandle); //생성자

cudaThreadSynchronize();

ㄴ유일무이한 유니언 객체 핸들을 반환, 디바이스여 여기에 집중하라! 같은 느낌, 그런이유로 당연히 쿠블라스외에도 쿠다를 제어하는 함수라면 폭넓게 사용됨

ㄴ반대로 소멸자에서 필수  cublasDestroy(cudaHandle); 

ㄴ생성자에서는 쿠블라스가 핸들을 수정할 수 있게 주소를 전달, 소멸자는 핸들값 자체만 활용하기 때문에 핸들 자체를 전달

ㄴ쿠블라스는 Nvidia의 선형대수lib

ㄴ쿠블라스 자체가 쿠다연산을 전제로 하기에 쓰레드싱크 필수

cudaMemcpy(mDeviceMemory, _A.mDeviceMemory, rows*cols*sizeof(*mDeviceMemory), cudaMemcpyDeviceToDevice); 

ㄴcudaError_t cudaMemcpy ( void* dst, const void* src, size_t _보통sizeof, cudaMemcpyKind _플래그 )

cublasStatus_t cublasError = cublasSgeam(_dstC.cudaHandle, // cublasSgeam() : R = aA + bB

                                        CUBLAS_OP_N, CUBLAS_OP_N, //N은 그대로, T는 전치

                                        rows, cols, 

                                        &alpha, mDeviceMemory, rows, `

                                        &beta, _srcB.mDeviceMemory, rows, 

                                        _dstC.mDeviceMemory, _dstC.rows);

ㄴ행렬mDeviceMemory와 _srcB의 선형조합을 계산하여 _dstC에 저장

ㄴalpha, beta는 스칼라

cublasStatus_t cublasError = cublasSgemm(cudaHandle, // R = aA * B + rR

                                        CUBLAS_OP_N, CUBLAS_OP_N, //A,B

                                        rows, _B.cols, cols, //AorC행(A고유), BorC열(B고유), A열orB행(AB공통)

                                        &a, mDeviceMemory, rows, 

                                        _B.mDeviceMemory, _B.rows,

                                        &c, _R.mDeviceMemory, _R.rows);

__device__ 쿠다디바이스키워드 : GPU에서 실행 / 다른 GPU함수에서 호출되는 함수임을 나타냄

__global__ 쿠다커널키워드 : GPU에서 실행 / CPU에서 호출되는 함수임을 나타냄 / for문 없이 주어진 함수는 모든 매트릭스에 대해 실행, 그 연산범위를 제한하고 싶은 경우 int threadPos_row = blockIdx.y * blockDim.y + threadIdx.y; 와 같이 쓰레드포지션을 인덱싱하여 if로 제한

__restrict__ 쿠다키워드 : 포인터가 다른 포인터와 곂치지 않음을 의미, 컴파일러에게 추가적인 최적화가능을 시

__forceinline__ 쿠다키워드 : 컴파일러레벨에서 인라인강제, 보통의 inline선언은 컴파일러판단하에 무시될수있음. 

__cplusplus 씨피피키워드 : cpp컴파일러에 의해 자동으로 정의되는 매크로, c/cpp조건분기 혹은 cpp버전을 확인용

ㄴextern "C" {cpp코드} 이런식으로 cpp코드를 C컴파일러로 처리할 수 있고 아래와 같이 #ifdef ~ #endif를 사용하여 C/C++상황에 모두 대응

#ifdef __cplusplus

    extern "C" {

#endif

        void mat_sqrt_kernel_exec(const float* src, float* dst, int m, int n, float alpha);

#ifdef __cplusplus

    };

#endif

[3] 퍼셉트론 & 다층퍼셉트론(MLP기본신경망)

[4] 오차역전파법(매개변수학습법)

[5] 이미지인식 및 분류모델구축 : MNIST손글씨데이터셋

[6] 오버피팅억제

[7] 오토인코더(매개변수의 사전학습)

[8] 합성곱신경망CNN, ConvolutionNeuralNetwork : CIFAR-10이미지데이터셋

[9] 재귀형신경망(인코더/디코더모델) : 자연어처리, 기계번역