Skip to content

WIP: Cuda Bindings #544

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"cc/core/Rect.cc",
"cc/core/RotatedRect.cc",
"cc/core/TermCriteria.cc",
"cc/core/FeatureSet.cc",
"cc/modules/io/io.cc",
"cc/modules/io/VideoCapture.cc",
"cc/modules/io/VideoWriter.cc",
Expand Down
21 changes: 21 additions & 0 deletions cc/core/FeatureSet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "FeatureSet.h"
#include "Mat.h"

Nan::Persistent<v8::FunctionTemplate> FeatureSet::constructor;

NAN_MODULE_INIT(FeatureSet::Init) {
v8::Local<v8::FunctionTemplate> ctor = Nan::New<v8::FunctionTemplate>(FeatureSet::New);
constructor.Reset(ctor);
ctor->InstanceTemplate()->SetInternalFieldCount(1);
ctor->SetClassName(Nan::New("FeatureSet").ToLocalChecked());

target->Set(Nan::New("FeatureSet").ToLocalChecked(), ctor->GetFunction());
};

NAN_METHOD(FeatureSet::New) {
FF_ASSERT_CONSTRUCT_CALL(FeatureSet);
FeatureSet* self = new FeatureSet();

self->Wrap(info.Holder());
info.GetReturnValue().Set(info.Holder());
};
15 changes: 15 additions & 0 deletions cc/core/FeatureSet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "macros.h"
#include <opencv2/core/cuda.hpp>

#ifndef __FF_FEATURESET_H__
#define __FF_FEATURESET_H__

class FeatureSet: public Nan::ObjectWrap {
public:
static NAN_MODULE_INIT(Init);
static NAN_METHOD(New);

static Nan::Persistent<v8::FunctionTemplate> constructor;
};

#endif
51 changes: 51 additions & 0 deletions cc/core/core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ NAN_MODULE_INIT(Core::Init) {
Rect::Init(target);
RotatedRect::Init(target);
TermCriteria::Init(target);
FeatureSet::Init(target);

Nan::SetMethod(target, "getBuildInformation", GetBuildInformation);
Nan::SetMethod(target, "partition", Partition);
Expand All @@ -45,6 +46,15 @@ NAN_MODULE_INIT(Core::Init) {
Nan::SetMethod(target, "getNumThreads", GetNumThreads);
Nan::SetMethod(target, "setNumThreads", SetNumThreads);
Nan::SetMethod(target, "getThreadNum", GetThreadNum);

// CUDA core
Nan::SetMethod(target, "deviceSupports", DeviceSupports);
Nan::SetMethod(target, "getCudaEnabledDeviceCount", GetCudaEnabledDeviceCount);
Nan::SetMethod(target, "getDevice", GetDevice);
Nan::SetMethod(target, "printCudaDeviceInfo", PrintCudaDeviceInfo);
Nan::SetMethod(target, "printShortCudaDeviceInfo", PrintShortCudaDeviceInfo);
Nan::SetMethod(target, "resetDevice", ResetDevice);
Nan::SetMethod(target, "setDevice", SetDevice);
};

NAN_METHOD(Core::GetBuildInformation) {
Expand Down Expand Up @@ -228,3 +238,44 @@ NAN_METHOD(Core::GetThreadNum) {
FF_METHOD_CONTEXT("Core::GetNumThreads");
FF_RETURN(IntConverter::wrap(cv::getThreadNum()));
}

// CUDA core
NAN_METHOD(Core::DeviceSupports) {
FF_METHOD_CONTEXT("Core::DeviceSupports");
FF_ARG_INT(0, int featureSet_int);
cv::cuda::FeatureSet featureSet = cv::cuda::FeatureSet(featureSet_int);
FF_RETURN(BoolConverter::wrap(cv::cuda::deviceSupports(featureSet)));
}

NAN_METHOD(Core::GetCudaEnabledDeviceCount) {
FF_METHOD_CONTEXT("Core::GetCudaEnabledDeviceCount");
FF_RETURN(IntConverter::wrap(cv::cuda::getCudaEnabledDeviceCount()));
}

NAN_METHOD(Core::GetDevice) {
FF_METHOD_CONTEXT("Core::GetDevice");
FF_RETURN(IntConverter::wrap(cv::cuda::getDevice()));
}

NAN_METHOD(Core::PrintCudaDeviceInfo) {
FF_METHOD_CONTEXT("Core::PrintCudaDeviceInfo");
FF_ARG_INT(0, int device);
cv::cuda::printCudaDeviceInfo(device);
}

NAN_METHOD(Core::PrintShortCudaDeviceInfo) {
FF_METHOD_CONTEXT("Core::PrintShortCudaDeviceInfo");
FF_ARG_INT(0, int device);
cv::cuda::printCudaDeviceInfo(device);
}

NAN_METHOD(Core::ResetDevice) {
FF_METHOD_CONTEXT("Cuda::ResetDevice");
cv::cuda::resetDevice();
}

NAN_METHOD(Core::SetDevice) {
FF_METHOD_CONTEXT("Core::SetDevice");
FF_ARG_INT(0, int device);
cv::cuda::setDevice(device);
}
11 changes: 11 additions & 0 deletions cc/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#include "Rect.h"
#include "RotatedRect.h"
#include "TermCriteria.h"
#include "FeatureSet.h"
#include "macros.h"
#include <opencv2/core.hpp>
#include <opencv2/core/cuda.hpp>

#ifndef __FF_CORE_H__
#define __FF_CORE_H__
Expand All @@ -25,6 +27,15 @@ class Core : public Nan::ObjectWrap {
static NAN_METHOD(GetNumThreads);
static NAN_METHOD(SetNumThreads);
static NAN_METHOD(GetThreadNum);

// CUDA core
static NAN_METHOD(DeviceSupports);
static NAN_METHOD(GetCudaEnabledDeviceCount);
static NAN_METHOD(GetDevice);
static NAN_METHOD(PrintCudaDeviceInfo);
static NAN_METHOD(PrintShortCudaDeviceInfo);
static NAN_METHOD(ResetDevice);
static NAN_METHOD(SetDevice);
};

#endif
19 changes: 19 additions & 0 deletions cc/cvTypes/cvTypes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,23 @@ void CvTypes::Init(v8::Local<v8::Object> target) {
FF_SET_CV_CONSTANT(target, DECOMP_SVD);
FF_SET_CV_CONSTANT(target, DECOMP_QR);
FF_SET_CV_CONSTANT(target, DECOMP_NORMAL);

// CUDA core
v8::Local<v8::Object> featureSetConstants = Nan::New<v8::Object>();
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_10, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_10));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_11, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_11));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_12, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_12));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_13, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_13));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_20, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_20));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_21, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_21));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_30, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_30));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_32, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_32));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_35, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_35));
FF_SET_JS_PROP(featureSetConstants, FEATURE_SET_COMPUTE_50, Nan::New<v8::Integer>(cv::cuda::FeatureSet::FEATURE_SET_COMPUTE_50));
FF_SET_JS_PROP(featureSetConstants, GLOBAL_ATOMICS, Nan::New<v8::Integer>(cv::cuda::FeatureSet::GLOBAL_ATOMICS));
FF_SET_JS_PROP(featureSetConstants, SHARED_ATOMICS, Nan::New<v8::Integer>(cv::cuda::FeatureSet::SHARED_ATOMICS));
FF_SET_JS_PROP(featureSetConstants, NATIVE_DOUBLE, Nan::New<v8::Integer>(cv::cuda::FeatureSet::NATIVE_DOUBLE));
FF_SET_JS_PROP(featureSetConstants, WARP_SHUFFLE_FUNCTIONS, Nan::New<v8::Integer>(cv::cuda::FeatureSet::WARP_SHUFFLE_FUNCTIONS));
FF_SET_JS_PROP(featureSetConstants, DYNAMIC_PARALLELISM, Nan::New<v8::Integer>(cv::cuda::FeatureSet::DYNAMIC_PARALLELISM));
target->Set(FF_NEW_STRING("featureSet"), featureSetConstants);
}
1 change: 1 addition & 0 deletions cc/cvTypes/cvTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/core/cuda.hpp>


#ifndef __FF_CVTYPES_H__
Expand Down
18 changes: 18 additions & 0 deletions lib/typings/constants.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,3 +599,21 @@ export const statModel: {
RAW_OUTPUT: number;
UPDATE_MODEL: number;
}

export const featureSet: {
FEATURE_SET_COMPUTE_10: number,
FEATURE_SET_COMPUTE_11: number,
FEATURE_SET_COMPUTE_12: number,
FEATURE_SET_COMPUTE_13: number,
FEATURE_SET_COMPUTE_20: number,
FEATURE_SET_COMPUTE_21: number,
FEATURE_SET_COMPUTE_30: number,
FEATURE_SET_COMPUTE_32: number,
FEATURE_SET_COMPUTE_35: number,
FEATURE_SET_COMPUTE_50: number,
GLOBAL_ATOMICS: number,
SHARED_ATOMICS: number,
NATIVE_DOUBLE: number,
WARP_SHUFFLE_FUNCTIONS: number,
DYNAMIC_PARALLELISM: number,
};
10 changes: 10 additions & 0 deletions lib/typings/cv.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,13 @@ export function isCustomMatAllocatorEnabled(): boolean;
export function dangerousEnableCustomMatAllocator(): boolean;
export function dangerousDisableCustomMatAllocator(): boolean;
export function getMemMetrics(): { TotalAlloc: number, TotalKnownByJS: number, NumAllocations: number, NumDeAllocations: number };

// CUDA core
// export const featureSet = FeatureSet;
// export function deviceSupports(featureSet: number) : boolean;
export function getCudaEnabledDeviceCount() : number;
export function getDevice() : number;
export function printCudaDeviceInfo(device: number) : void;
export function printShortCudaDeviceInfo(device: number) : void;
export function resetDevice() : void;
export function setDevice(device: number) : void;
107 changes: 107 additions & 0 deletions test/tests/core/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,110 @@ describe('core', () => {
})
}
});

describe('core - cuda', () => {
describe('deviceSupports', () => {
it('should have function deviceSupports', () => {
expect(cv).to.have.property('deviceSupports').to.be.a('function');
});

it('should have access to featureSet enum', () => {
expect(cv).to.have.property('featureSet').to.be.an('object');
});

generateAPITests({
getDut: () => cv,
methodName: 'deviceSupports',
hasAsync: false,
getRequiredArgs: () => ([
cv.featureSet.FEATURE_SET_COMPUTE_10,
]),
expectOutput: res => expect(res).to.be.a('boolean'),
usesMacroInferno: true,
});
});

describe('getCudaEnabledDeviceCount', () => {
it('should have function getCudaEnabledDeviceCount', () => {
expect(cv).to.have.property('getCudaEnabledDeviceCount').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'getCudaEnabledDeviceCount',
hasAsync: false,
expectOutput: res => expect(res).to.be.a('number'),
});
});

describe('getDevice', () => {
it('should have function getDevice', () => {
expect(cv).to.have.property('getDevice').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'getDevice',
hasAsync: false,
expectOutput: res => expect(res).to.be.a('number'),
});
});

describe('printCudaDeviceInfo', () => {
it('should have function printCudaDeviceInfo', () => {
expect(cv).to.have.property('printCudaDeviceInfo').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'printCudaDeviceInfo',
hasAsync: false,
getRequiredArgs: () => [1],
expectOutput: () => {},
usesMacroInferno: true,
});
});

describe('printShortCudaDeviceInfo', () => {
it('should have function printShortCudaDeviceInfo', () => {
expect(cv).to.have.property('printShortCudaDeviceInfo').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'printShortCudaDeviceInfo',
hasAsync: false,
getRequiredArgs: () => [1],
expectOutput: () => {},
usesMacroInferno: true,
});
});

describe('resetDevice', () => {
it('should have function resetDevice', () => {
expect(cv).to.have.property('resetDevice').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'resetDevice',
hasAsync: false,
expectOutput: () => {},
});
});

describe('setDevice', () => {
it('should have function setDevice', () => {
expect(cv).to.have.property('setDevice').to.be.a('function');
});

generateAPITests({
getDut: () => cv,
methodName: 'setDevice',
hasAsync: false,
getRequiredArgs: () => [0],
expectOutput: () => {},
usesMacroInferno: true,
});
});
});