From 07a9105a5214c3959b1597a462baec41f5826e62 Mon Sep 17 00:00:00 2001 From: Berenger Bramas <Berenger.Bramas@inria.fr> Date: Thu, 28 Jan 2016 11:45:05 +0100 Subject: [PATCH] add cuda help classes (mem object and timer) --- Src/GroupTree/Cuda/FCudaData.hpp | 77 +++++++++++++++++++++++ Src/GroupTree/Cuda/FCudaTic.hpp | 102 +++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 Src/GroupTree/Cuda/FCudaData.hpp create mode 100644 Src/GroupTree/Cuda/FCudaTic.hpp diff --git a/Src/GroupTree/Cuda/FCudaData.hpp b/Src/GroupTree/Cuda/FCudaData.hpp new file mode 100644 index 000000000..49c501152 --- /dev/null +++ b/Src/GroupTree/Cuda/FCudaData.hpp @@ -0,0 +1,77 @@ +#ifndef FCUDADATA_HPP +#define FCUDADATA_HPP + +#include "FCudaGlobal.hpp" + +template <class ObjectClass> +class FCudaData{ +protected: + ObjectClass* cudaPtr; + FSize nbElements; + + void allocAndCopy(const ObjectClass* inCpuPtr, const FSize inNbElements){ + FCudaCheck( cudaMalloc(&cudaPtr,inNbElements*sizeof(ObjectClass)) ); + FCudaCheck( cudaMemcpy( cudaPtr, inCpuPtr, inNbElements*sizeof(ObjectClass), + cudaMemcpyHostToDevice ) ); + } + + void dealloc(){ + FCudaCheck(cudaFree(cudaPtr)); + cudaPtr = nullptr; + nbElements = 0; + } +public: + FCudaData(const FCudaData&) = delete; + FCudaData& operator=(const FCudaData&) = delete; + + FCudaData(const ObjectClass* inCpuPtr, const FSize inNbElements) + : cudaPtr(nullptr), nbElements(0){ + allocAndCopy(inCpuPtr, inNbElements); + } + + + FCudaData(FCudaData&& other) + : cudaPtr(nullptr), nbElements(0){ + this->cudaPtr = other->cudaPtr; + this->nbElements = other->nbElements; + other->cudaPtr = nullptr; + other->nbElements = 0; + } + + FCudaData& operator=(FCudaData&& other){ + dealloc(); + this->cudaPtr = other->cudaPtr; + this->nbElements = other->nbElements; + other->cudaPtr = nullptr; + other->nbElements = 0; + } + + + ~FCudaData(){ + dealloc(); + } + + void release(){ + dealloc(); + } + + ObjectClass* get() { + return cudaPtr; + } + + const ObjectClass* get() const { + return cudaPtr; + } + + FSize getSize() const { + return nbElements; + } + + void copyToHost(ObjectClass* inCpuPtr){ + FCudaCheck( cudaMemcpy( inCpuPtr, cudaPtr, nbElements*sizeof(ObjectClass), + cudaMemcpyDeviceToHost ) ); + } +}; + +#endif // FCUDADATA_HPP + diff --git a/Src/GroupTree/Cuda/FCudaTic.hpp b/Src/GroupTree/Cuda/FCudaTic.hpp new file mode 100644 index 000000000..9d75a0e06 --- /dev/null +++ b/Src/GroupTree/Cuda/FCudaTic.hpp @@ -0,0 +1,102 @@ +#ifndef FCUDATIC_HPP +#define FCUDATIC_HPP + +#include "FCudaGlobal.hpp" + + +/** + * \brief Time counter class. + * \author Berenger Bramas (berenger.bramas@inria.fr) + * + * This time counter can be (re)started using tic() and stopped using tac(). + * + * - use elapsed() to get the last time interval; + * - use cumulated() to get the total running time; + * - use reset() to stop and reset the counter. + * + * \code + * FCudaTic timer; + * timer.tic(); + * //...(1) + * timer.tac(); + * timer.elapsed(); // time of (1) in s + * timer.tic(); + * //...(2) + * timer.tac(); + * timer.elapsed(); // time of (2) in s + * timer.cumulated() // time of (1) and (2) in s + * timer.reset() // reset the object + * \endcode + * + */ +class FCudaTic { +private: + + cudaStream_t stream; + cudaEvent_t start = 0; ///< start time (tic) + cudaEvent_t end = 0; ///< stop time (tac) + double cumulate = 0; ///< the cumulate time + +public: + /// Constructor + explicit FCudaTic(const cudaStream_t inStream = 0) + : stream(inStream){ + FCudaCheck(cudaEventCreate(&start)); + FCudaCheck(cudaEventCreate(&end)); + tic(); + } + + ~FCudaTic(){ + FCudaCheck( cudaEventDestroy( start ) ); + FCudaCheck( cudaEventDestroy( end ) ); + } + + /// Copy constructor + FCudaTic(const FCudaTic& other) = delete; + /// Copy operator + FCudaTic& operator=(const FCudaTic& other) = delete; + + + /// Resets the timer + /**\warning Use tic() to restart the timer. */ + void reset() { + cumulate = 0; + } + + /// Start measuring time. + void tic(){ + FCudaCheck(cudaEventRecord( start, stream )); + } + + /// Stop measuring time and add to cumulated time. + void tac(){ + FCudaCheck(cudaEventRecord( end, stream )); + FCudaCheck(cudaEventSynchronize( end )); + cumulate += elapsed(); + } + + /// Elapsed time between the last tic() and tac() (in seconds). + /** \return the time elapsed between tic() & tac() in second. */ + double elapsed() const{ + float elapsedTime; + FCudaCheck( cudaEventElapsedTime( &elapsedTime, start, end ) ); // in ms + return elapsedTime/1000.0; + } + + /// Cumulated tic() - tac() time spans + /** \return the time elapsed between ALL tic() & tac() in second. */ + double cumulated() const{ + return cumulate; + } + + /// Combination of tic() and elapsed(). + /** \return the time elapsed between tic() & tac() in second. */ + double tacAndElapsed() { + tac(); + return elapsed(); + } +}; + + +#endif // FCUDATIC_HPP + -- GitLab