Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract CCTags from multiple images in parallel #32

Merged
merged 15 commits into from
Aug 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/applications/detection/CmdLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static const struct option longopts[] =
{"sync", no_argument, 0, 0xd0 },
{"debug-dir", required_argument, 0, 0xd1 },
{"use-cuda", no_argument, 0, 0xd2 },
{"parallel", required_argument, 0, 0xd3 },
#endif
{0,0,0,0},
};
Expand All @@ -42,6 +43,7 @@ CmdLine::CmdLine( )
, _switchSync( false )
, _debugDir( "" )
, _useCuda( false )
, _parallel( 1 )
#endif
{ }

Expand Down Expand Up @@ -72,6 +74,7 @@ bool CmdLine::parse( int argc, char* argv[] )
case 0xd0 : _switchSync = true; break;
case 0xd1 : _debugDir = optarg; break;
case 0xd2 : _useCuda = true; break;
case 0xd3 : _parallel = strtol( optarg, NULL, 0 ); break;
#endif
default : break;
}
Expand Down Expand Up @@ -111,6 +114,7 @@ void CmdLine::usage( const char* const argv0 )
" [--sync]\n"
" [--debug-dir <debugdir>]\n"
" [--use-cuda]\n"
" [--parallel <n>]\n"
"\n"
" <imgpath> - path to an image (JPG, PNG) or video\n"
" <nbrings> - number of rings of the CCTags to detect\n"
Expand All @@ -120,6 +124,7 @@ void CmdLine::usage( const char* const argv0 )
" --sync - CUDA debug option, run all CUDA ops synchronously\n"
" <debugdir> - path storing image to debug intermediate GPU results\n"
" --use-cuda - select GPU code instead of CPU code\n"
" --parallel - use <n> CUDA pipes concurrently (default 1)\n"
"\n" << std::endl;
}

Expand Down
1 change: 1 addition & 0 deletions src/applications/detection/CmdLine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class CmdLine
bool _switchSync;
std::string _debugDir;
bool _useCuda;
int _parallel;
#endif

CmdLine( );
Expand Down
58 changes: 38 additions & 20 deletions src/applications/detection/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <fstream>
#include <exception>

#include <tbb/tbb.h>

#define PRINT_TO_CERR

using namespace cctag;
Expand All @@ -49,7 +51,13 @@ using boost::timer;
using namespace boost::gil;
namespace bfs = boost::filesystem;

void detection(std::size_t frameId, const cv::Mat & src, const cctag::Parameters & params, const cctag::CCTagMarkersBank & bank, std::ostream & output, std::string debugFileName = "")
void detection( std::size_t frameId,
int pipeId,
const cv::Mat & src,
const cctag::Parameters & params,
const cctag::CCTagMarkersBank & bank,
std::ostream & output,
std::string debugFileName = "")
{

if (debugFileName == "") {
Expand All @@ -67,7 +75,7 @@ void detection(std::size_t frameId, const cv::Mat & src, const cctag::Parameters
static cctag::logtime::Mgmt* durations = 0;

//Call the main CCTag detection function
cctagDetection( markers, frameId , src, params, bank, true, durations );
cctagDetection( markers, pipeId, frameId , src, params, bank, true, durations );

if( durations ) {
durations->print( std::cerr );
Expand Down Expand Up @@ -208,10 +216,11 @@ int main(int argc, char** argv)
cv::Mat graySrc;
cv::cvtColor( src, graySrc, CV_BGR2GRAY );

const int pipeId = 0;
#ifdef PRINT_TO_CERR
detection(0, graySrc, params, bank, std::cerr, myPath.stem().string());
detection(0, pipeId, graySrc, params, bank, std::cerr, myPath.stem().string());
#else
detection(0, graySrc, params, bank, outputFile, myPath.stem().string());
detection(0, pipeId, graySrc, params, bank, outputFile, myPath.stem().string());
#endif
} else if (ext == ".avi" )
{
Expand Down Expand Up @@ -259,10 +268,11 @@ int main(int argc, char** argv)
//bitwise_not ( imgGray, imgGrayInverted );

// Call the CCTag detection
const int pipeId = 0;
#ifdef PRINT_TO_CERR
detection(frameId, *imgGray, params, bank, std::cerr, outFileName.str());
detection(frameId, pipeId, *imgGray, params, bank, std::cerr, outFileName.str());
#else
detection(frameId, *imgGray, params, bank, outputFile, outFileName.str());
detection(frameId, pipeId, *imgGray, params, bank, outputFile, outFileName.str());
#endif
++frameId;
if( frameId % 100 == 0 ) {
Expand All @@ -280,30 +290,38 @@ int main(int argc, char** argv)

std::size_t frameId = 0;

std::map<int,bfs::path> files[2];
for(const auto & fileInFolder : vFileInFolder) {
const std::string subExt(bfs::extension(fileInFolder));
files[frameId & 1].insert( std::pair<int,bfs::path>( frameId, fileInFolder ) );
frameId++;
}

tbb::parallel_for( 0, 2, [&](size_t fileListIdx) {
for(const auto & fileInFolder : files[fileListIdx]) {
const std::string subExt(bfs::extension(fileInFolder.second));

if ( (subExt == ".png") || (subExt == ".jpg") || (subExt == ".PNG") || (subExt == ".JPG") ) {
if ( (subExt == ".png") || (subExt == ".jpg") || (subExt == ".PNG") || (subExt == ".JPG") ) {

CCTAG_COUT( "Processing image " << fileInFolder.string() );
std::cerr << "Processing image " << fileInFolder.second.string() << std::endl;

cv::Mat src;
src = cv::imread(fileInFolder.string());
cv::Mat src;
src = cv::imread(fileInFolder.second.string());

cv::Mat imgGray;
cv::cvtColor( src, imgGray, CV_BGR2GRAY );
cv::Mat imgGray;
cv::cvtColor( src, imgGray, CV_BGR2GRAY );

// Call the CCTag detection
// Call the CCTag detection
int pipeId = ( fileInFolder.first & 1 );
#ifdef PRINT_TO_CERR
detection(frameId, imgGray, params, bank, std::cerr, fileInFolder.stem().string());
detection(fileInFolder.first, pipeId, imgGray, params, bank, std::cerr, fileInFolder.second.stem().string());
#else
detection(frameId, imgGray, params, bank, outputFile, fileInFolder.stem().string());
detection(fileInFolder.first, pipeId, imgGray, params, bank, outputFile, fileInFolder.second.stem().string());
#endif
++frameId;
std::cerr << "Done processing image " << fileInFolder.second.string() << std::endl;
}
}
}
}else
{
} );
} else {
throw std::logic_error("Unrecognized input.");
}
outputFile.close();
Expand Down
2 changes: 1 addition & 1 deletion src/applications/regression/TestLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ FrameLog FrameLog::detect(size_t frame, const cv::Mat& src, const Parameters& pa
CCTag::List markers;

const auto t0 = high_resolution_clock::now();
cctagDetection(markers, frame, src, parameters, bank, true, nullptr);
cctagDetection(markers, 0, frame, src, parameters, bank, true, nullptr);
const auto t1 = high_resolution_clock::now();
const auto td = duration_cast<milliseconds>(t1 - t0).count() / 1000.f;

Expand Down
8 changes: 4 additions & 4 deletions src/cctag/CCTag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ void CCTag::scale(const float s)
}

#ifdef WITH_CUDA
void CCTag::acquireNearbyPointMemory( )
void CCTag::acquireNearbyPointMemory( int tagId )
{
_cuda_result = popart::PinnedCounters::getPointPtr( __FILE__, __LINE__ );
_cuda_result = popart::PinnedCounters::getPointPtr( tagId, __FILE__, __LINE__ );
}

void CCTag::releaseNearbyPointMemory( )
void CCTag::releaseNearbyPointMemory( int tagId )
{
popart::PinnedCounters::releaseAllPoints();
popart::PinnedCounters::releaseAllPoints( tagId );
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/cctag/CCTag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ class CCTag : public ICCTag
* Instead, releaseNearbyPointMemory() invalidates all such
* pointers in the process.
*/
void acquireNearbyPointMemory( );
void acquireNearbyPointMemory( int pipeId );

inline popart::NearbyPoint* getNearbyPointBuffer( ) {
return _cuda_result;
Expand All @@ -363,7 +363,7 @@ class CCTag : public ICCTag
* Invalidates pointers in all objects and in all threads in
* this process.
*/
static void releaseNearbyPointMemory( );
static void releaseNearbyPointMemory( int pipeId );
#endif

void serialize(boost::archive::text_oarchive & ar, const unsigned int version);
Expand Down
19 changes: 10 additions & 9 deletions src/cctag/Detection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,9 @@ popart::TagPipe* initCuda( int pipeId,
* @param[in] bank CCTag bank.
* @param[in] No longer used.
*/
void cctagDetection(CCTag::List& markers,
void cctagDetection(
CCTag::List& markers,
int pipeId,
const std::size_t frame,
const cv::Mat & imgGraySrc,
const Parameters & providedParams,
Expand Down Expand Up @@ -807,7 +809,7 @@ void cctagDetection(CCTag::List& markers,
popart::TagPipe* pipe1 = 0;
#ifdef WITH_CUDA
if( params._useCuda ) {
pipe1 = initCuda( 0,
pipe1 = initCuda( pipeId,
imgGraySrc.size().width,
imgGraySrc.size().height,
params,
Expand All @@ -820,7 +822,7 @@ void cctagDetection(CCTag::List& markers,
assert( imgGraySrc.type() == CV_8U );
unsigned char* pix = imgGraySrc.data;

pipe1->load( pix );
pipe1->load( frame, pix );

if( durations ) {
cudaDeviceSynchronize();
Expand Down Expand Up @@ -870,7 +872,7 @@ void cctagDetection(CCTag::List& markers,
}

for( CCTag& tag : markers ) {
tag.acquireNearbyPointMemory( );
tag.acquireNearbyPointMemory( pipe1->getId() );
}
}
#endif // WITH_CUDA
Expand Down Expand Up @@ -913,13 +915,12 @@ void cctagDetection(CCTag::List& markers,
if( pipe1 && numTags > 0 ) {
pipe1->uploadCuts( numTags, vSelectedCuts, params );

// cerr << __FILE__ << ":"<< __LINE__ << " WARNING: uncontrolled creation of CUDA streams!!!!" << endl;
pipe1->makeCudaStreams( numTags );

tagIndex = 0;
int debug_num_calls = 0;
for( CCTag& cctag : markers ) {
if( detected[tagIndex] == status::id_reliable ) {
if( vSelectedCuts[tagIndex].size() <= 2 ) {
detected[tagIndex] = status::no_selected_cuts;
} else if( detected[tagIndex] == status::id_reliable ) {
if( debug_num_calls >= numTags ) {
cerr << __FILE__ << ":" << __LINE__ << " center finding for more loops (" << debug_num_calls << ") than uploaded (" << numTags << ")?" << endl;
}
Expand Down Expand Up @@ -969,7 +970,7 @@ void cctagDetection(CCTag::List& markers,
if( pipe1 ) {
/* Releasing all points in all threads in the process.
*/
CCTag::releaseNearbyPointMemory();
CCTag::releaseNearbyPointMemory( pipe1->getId() );
}
#endif

Expand Down
2 changes: 2 additions & 0 deletions src/cctag/Detection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class EdgePointImage;
* @brief Perform the CCTag detection on a gray scale image. Cf. application/detection/main.cpp for example of usage.
*
* @param[out] markers Detected markers. WARNING: only markers with status == 1 are valid ones. (status available via getStatus())
* @param[in] pipeId Choose one of up to 3 parallel CUDA pipes
* @param[in] frame A frame number. Can be anything (e.g. 0).
* @param[in] imgGraySrc Gray scale input image.
* @param[in] providedParams Contains all the parameters.
Expand All @@ -41,6 +42,7 @@ class EdgePointImage;
*/
void cctagDetection(
CCTag::List& markers,
int pipeId,
const std::size_t frame,
const cv::Mat & graySrc,
const Parameters & params,
Expand Down
9 changes: 6 additions & 3 deletions src/cctag/ICCTag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace cctag {
* @brief Perform the CCTag detection on a gray scale image
*
* @param[out] markers Detected markers. WARNING: only markers with status == 1 are valid ones. (status available via getStatus())
* @param[in] pipeId Choose between several CUDA pipeline instances
* @param[in] frame A frame number. Can be anything (e.g. 0).
* @param[in] graySrc Gray scale input image.
* @param[in] nRings Number of CCTag rings.
Expand All @@ -33,6 +34,7 @@ namespace cctag {
*/
void cctagDetection(
boost::ptr_list<ICCTag> & markers,
int pipeId,
const std::size_t frame,
const cv::Mat & graySrc,
const std::size_t nRings,
Expand Down Expand Up @@ -63,11 +65,12 @@ void cctagDetection(
bank = CCTagMarkersBank(cctagBankFilename);
}

cctagDetection(markers, frame, graySrc, params, durations, &bank);
cctagDetection(markers, pipeId, frame, graySrc, params, durations, &bank);
}

void cctagDetection(
boost::ptr_list<ICCTag> & markers,
int pipeId,
const std::size_t frame,
const cv::Mat & graySrc,
const cctag::Parameters & params,
Expand All @@ -79,10 +82,10 @@ void cctagDetection(
if ( pBank == NULL)
{
CCTagMarkersBank bank(params._nCrowns);
cctag::cctagDetection(cctags, frame, graySrc, params, bank, false, durations);
cctag::cctagDetection(cctags, pipeId, frame, graySrc, params, bank, false, durations);
}else
{
cctag::cctagDetection(cctags, frame, graySrc, params, *pBank, false, durations);
cctag::cctagDetection(cctags, pipeId, frame, graySrc, params, *pBank, false, durations);
}

markers.clear();
Expand Down
2 changes: 2 additions & 0 deletions src/cctag/ICCTag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ICCTag
*/
void cctagDetection(
boost::ptr_list<ICCTag> & markers,
int pipeId,
const std::size_t frame,
const cv::Mat & graySrc,
logtime::Mgmt* durations = 0,
Expand All @@ -72,6 +73,7 @@ void cctagDetection(

void cctagDetection(
boost::ptr_list<ICCTag> & markers,
int pipeId,
const std::size_t frame,
const cv::Mat & graySrc,
const cctag::Parameters & params,
Expand Down
Loading