Commit 07a9105a authored by BRAMAS Berenger's avatar BRAMAS Berenger

add cuda help classes (mem object and timer)

parent 73e71b6e
#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
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment