Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
af88b0d5
Commit
af88b0d5
authored
Aug 10, 2017
by
Davis King
Browse files
Options
Browse Files
Download
Plain Diff
merged
parents
d9f93548
d62c5a7c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
771 additions
and
289 deletions
+771
-289
cmake_swig_jni
dlib/java/cmake_swig_jni
+19
-1
java_array.h
dlib/java/java_array.h
+601
-0
jvector.h
dlib/java/jvector.h
+0
-250
swig_api.h
dlib/java/swig_api.h
+58
-33
swig_test.java
dlib/java/swig_test.java
+15
-0
matrix_blas_bindings.h
dlib/matrix/matrix_blas_bindings.h
+2
-2
matrix_mat.h
dlib/matrix/matrix_mat.h
+31
-2
matrix_mat_abstract.h
dlib/matrix/matrix_mat_abstract.h
+29
-0
dnn.cpp
dlib/test/dnn.cpp
+1
-1
matrix.cpp
dlib/test/matrix.cpp
+15
-0
No files found.
dlib/java/cmake_swig_jni
View file @
af88b0d5
...
...
@@ -119,8 +119,26 @@ FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/swig.i
%module global
%{
#include \"swig_api.h\"
#include <exception>
#include <stdexcept>
static JavaVM *cached_jvm = 0;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
cached_jvm = jvm;
return JNI_VERSION_1_6;
}
static JNIEnv * JNI_GetEnv() {
JNIEnv *env;
jint rc = cached_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
if (rc == JNI_EDETACHED)
throw std::runtime_error(\"current thread not attached\");
if (rc == JNI_EVERSION)
throw std::runtime_error(\"jni version not supported\");
return env;
}
#include \"swig_api.h\"
%}
// Convert all C++ exceptions into java.lang.Exception
...
...
dlib/java/java_array.h
0 → 100644
View file @
af88b0d5
// Copyright (C) 2017 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SWIG_JAVA_ARRAY_H_
#define DLIB_SWIG_JAVA_ARRAY_H_
/*
This file defines three special classes: array, array_view, and array_view_crit. An
array is a simple opaque handle to a java array, like a double[] array. The array_view
and array_view_crit objects allow you to access the contents of an array. The
interfaces of these objects is shown below, but for an example use, suppose you had an
array of int in java and you wanted to pass it to C++. You could create a C++ function
like this:
void my_function(const array_view<int32_t>& array);
and then within java you could call it with code like this:
int[] array = new int[100];
my_function(array);
and it will work just like you would expect. The array_view<int32_t> will usually result in
the JVM doing a copy in the background. However, you can also declare your function
like this:
void my_function(const array_view_crit<int32_t>& array);
and still call it the same way in java, however, using array_view_crit<int32_t> will usually
not result in any copying, and is therefore very fast. array_view_crit uses the JNI
routine GetPrimitiveArrayCritical() to get a lock on the java memory underlying the
array. So it will probably prevent the garbage collector from running while your
function is executing. The JNI documentation is somewhat vague on the limitations of
GetPrimitiveArrayCritical(), saying only that you shouldn't hold the lock on the array
for "an extended period" or call back into the JVM. Deciding whether or not this
matters in your application is left as an exercise for the reader.
There are two ways you can declare your methods if they take an array_view or
array_view_crit. Taking a const reference or a non-const reference. E.g.
void my_function(const array_view<int32_t>& array);
void my_function(array_view<int32_t>& array);
You can't declare them to be by value. The non-const version allows you to modify the
contents of the array and the modifications will be visible to java, as you would
expect. You can also make functions that take array objects directly, but that's only
useful if you want to store the array handle somewhere, like in a member of a long
lived class. You can also write functions that return arrays back to java. E.g.
array<int32_t> make_an_array(size_t s)
{
array<int32_t> arr(s);
array_view<int32_t> aview(arr);
// Use aview to put data into the array and generally do something useful.
...
return arr;
}
This would create an array and return it as a java int[] array.
You can also of course use functions taking many arguments, as is normally the case
with SWIG. Finally, these classes work with the following primitive types:
- int16_t
- int32_t
- int64_t
- char (corresponding to java byte)
- float
- double
namespace java
{
template <typename T>
class array
{
/!*
WHAT THIS OBJECT REPRESENTS
This is a handle to a java array. I.e. a reference to an array instance in
java like a double[] or int[]. It doesn't do anything other than tell you
the size of the array and allow you to hold a reference to it.
To access the array contents, you need to create an array_view or
array_view_crit from the array.
*!/
public:
array();
/!*
ensures
- #size() == 0
- this array is a null reference, i.e. it doesn't reference any array.
*!/
explicit array(size_t new_size);
/!*
ensures
- #size() == new_size
- Allocates a new java array.
- This array is a reference to the newly allocated java array object.
*!/
size_t size() const;
/!*
ensures
- returns the number of elements in this java array.
*!/
void swap(array& item);
/!*
ensures
- swaps the state of *this and item.
*!/
array(const array& item);
array& operator= (const array& item)
array(array&& item);
array& operator= (array&& item);
/!*
ensures
- The array is copyable, assignable, and movable. All copies will
reference the same underlying array. So the copies are shallow, as is
normally the case with java reference semantics.
*!/
};
template <typename T>
class array_view
{
/!*
WHAT THIS OBJECT REPRESENTS
This is a view into a java array object. It allows you to access the
values stored in an array and modify them if you want to.
You should only create array_view objects locally in a function since an
array_view is only valid as long as the array it references exists. So
don't store array_view objects in the member area of a class or globally.
*!/
public:
array_view();
/!*
ensures
- #size() == 0
- #data() == nullptr
*!/
array_view(const array<T>& arr, bool might_be_modified=true);
/!*
ensures
- #size() == arr.size()
- #data() == a pointer to the beginning of the array data referenced by arr.
- When you get a view on a java array, sometimes the JVM will actually
give you a pointer to a copy of the original array. You therefore have
to tell the JVM if you modified the array when you are done using it. If
you say you modified it then the JVM will perform another copy from your
memory buffer back into the JVM. The state of might_be_modified controls
if we do this. So if you are going to modify the array via this
array_view you should set might_be_modified==true.
*!/
size_t size() const;
/!*
ensures
- returns the number of elements in this java array.
*!/
T* data();
const T* data() const;
/!*
ensures
- returns a pointer to the beginning of the array. Or nullptr if this is a
handle to null, rather than an actual array instance.
*!/
T* begin();
T* end();
const T* begin() const;
const T* end() const;
/!*
ensures
- returns iterators to the start and one-past-the-end of the array, as is
the convention for iterator ranges in C++.
*!/
T& operator[](size_t i);
const T& operator[](size_t i) const;
/!*
ensures
- returns data()[i]
*!/
private:
// this object is non-copyable.
array_view(const array_view&);
array_view& operator=(const array_view&);
};
template <typename T>
class array_view_crit
{
/!*
WHAT THIS OBJECT REPRESENTS
This is just like an array_view and has an identical interface. The only
difference is that we use the JNI call GetPrimitiveArrayCritical() to get a
critical lock on the array's memory. Therefore, using array_view_crit is
usually faster than array_view since it avoids any unnecessary copying back
and forth between the JVM.
However, this critical lock can block the JVM's garbage collector from
running. So don't create long lived array_view_crit objects.
*!/
};
}
*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// IMPLEMENTATION DETAILS
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
namespace
java
{
template
<
typename
T
>
class
array_view_base
{
public
:
array_view_base
()
=
default
;
size_t
size
()
const
{
return
sz
;
}
T
*
data
()
{
return
pdata
;
}
const
T
*
data
()
const
{
return
pdata
;
}
T
*
begin
()
{
return
pdata
;
}
T
*
end
()
{
return
pdata
+
sz
;
}
const
T
*
begin
()
const
{
return
pdata
;
}
const
T
*
end
()
const
{
return
pdata
+
sz
;
}
T
&
operator
[](
size_t
i
)
{
return
pdata
[
i
];
}
const
T
&
operator
[](
size_t
i
)
const
{
return
pdata
[
i
];
}
protected
:
T
*
pdata
=
nullptr
;
size_t
sz
=
0
;
private
:
// this object is non-copyable
array_view_base
(
const
array_view_base
&
);
array_view_base
&
operator
=
(
const
array_view_base
&
);
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
struct
find_java_array_type
;
template
<>
struct
find_java_array_type
<
int16_t
>
{
typedef
jshortArray
type
;
};
template
<>
struct
find_java_array_type
<
int32_t
>
{
typedef
jintArray
type
;
};
template
<>
struct
find_java_array_type
<
int64_t
>
{
typedef
jlongArray
type
;
};
template
<>
struct
find_java_array_type
<
char
>
{
typedef
jbyteArray
type
;
};
template
<>
struct
find_java_array_type
<
float
>
{
typedef
jfloatArray
type
;
};
template
<>
struct
find_java_array_type
<
double
>
{
typedef
jdoubleArray
type
;
};
jshortArray
create_java_array
(
int16_t
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewShortArray
(
size
);
}
jintArray
create_java_array
(
int32_t
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewIntArray
(
size
);
}
jlongArray
create_java_array
(
int64_t
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewLongArray
(
size
);
}
jbyteArray
create_java_array
(
char
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewByteArray
(
size
);
}
jfloatArray
create_java_array
(
float
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewFloatArray
(
size
);
}
jdoubleArray
create_java_array
(
double
,
size_t
size
)
{
return
JNI_GetEnv
()
->
NewDoubleArray
(
size
);
}
template
<
typename
T
>
class
array
{
public
:
typedef
typename
find_java_array_type
<
T
>::
type
java_type
;
array
()
{}
explicit
array
(
size_t
size
)
{
ref
=
create_java_array
(
T
(),
size
);
is_global_ref
=
false
;
}
array
(
java_type
ref_
)
{
if
(
ref_
)
{
ref
=
(
java_type
)
JNI_GetEnv
()
->
NewGlobalRef
(
ref_
);
is_global_ref
=
true
;
}
}
#ifndef SWIG
array
(
array
&&
item
)
{
ref
=
item
.
ref
;
is_global_ref
=
item
.
is_global_ref
;
item
.
ref
=
NULL
;
item
.
is_global_ref
=
false
;
}
array
&
operator
=
(
array
&&
item
)
{
array
(
std
::
move
(
item
)).
swap
(
*
this
);
return
*
this
;
}
#endif
~
array
()
{
if
(
ref
)
{
// Don't delete the reference if it's a local reference, since the only reason
// we will normally be using array object's that contain local references
// is because we plan on returning the newly constructed array back to the JVM,
// which automatically frees local references using the normal JVM garbage
// collection scheme.
if
(
is_global_ref
)
JNI_GetEnv
()
->
DeleteGlobalRef
(
ref
);
ref
=
NULL
;
is_global_ref
=
false
;
}
}
size_t
size
()
const
{
if
(
ref
)
return
JNI_GetEnv
()
->
GetArrayLength
(
ref
);
else
return
0
;
}
array
(
const
array
&
item
)
{
array
(
item
.
ref
).
swap
(
*
this
);
}
array
&
operator
=
(
const
array
&
item
)
{
array
(
item
).
swap
(
*
this
);
return
*
this
;
}
operator
java_type
()
const
{
return
ref
;}
void
swap
(
array
&
item
)
{
std
::
swap
(
ref
,
item
.
ref
);
}
private
:
java_type
ref
=
NULL
;
bool
is_global_ref
=
false
;
};
#ifdef SWIG
// Tell SWIG to not use it's SwigValueWrapper stuff on array objects since they aren't
// needed and it causes superfluous construction and destruction of array objects.
%
feature
(
"novaluewrapper"
)
array
<
int16_t
>
;
%
template
()
array
<
int16_t
>
;
%
feature
(
"novaluewrapper"
)
array
<
int32_t
>
;
%
template
()
array
<
int32_t
>
;
%
feature
(
"novaluewrapper"
)
array
<
int64_t
>
;
%
template
()
array
<
int64_t
>
;
%
feature
(
"novaluewrapper"
)
array
<
char
>
;
%
template
()
array
<
char
>
;
%
feature
(
"novaluewrapper"
)
array
<
float
>
;
%
template
()
array
<
float
>
;
%
feature
(
"novaluewrapper"
)
array
<
double
>
;
%
template
()
array
<
double
>
;
#endif
#ifdef SWIG
%
define
tostring
(
token
)
#token
%
enddef
%
define
define_javaObjectRef_converion
(
type
,
java_type
)
// Define array conversions for non-const arrays
%
typemap
(
jtype
)
(
array
<
type
>
)
"java_type[]"
%
typemap
(
jstype
)
(
array
<
type
>
)
"java_type[]"
%
typemap
(
jni
)
(
array
<
type
>
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
array
<
type
>
)
"$javainput"
%
typemap
(
in
)
(
array
<
type
>
)
{
$
1
=
array
<
type
>
(
$
input
);
}
%
typemap
(
javaout
)
(
array
<
type
>
)
{
return
$
jnicall
;
}
%
typemap
(
out
)
(
array
<
type
>
)
{
jresult
=
result
;}
%
typemap
(
jtype
)
(
array
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
array
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
array
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
array
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
array
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
array
<
type
>&
)
(
array
<
type
>
temp
)
{
*
(
$
1
)
=
array
<
type
>
(
$
input
);
}
%
typemap
(
jtype
)
(
const
array
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
const
array
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
const
array
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
const
array
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
const
array
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
const
array
<
type
>&
)
(
array
<
type
>
temp
)
{
*
(
$
1
)
=
array
<
type
>
(
$
input
);
}
%
enddef
define_javaObjectRef_converion
(
int16_t
,
short
)
define_javaObjectRef_converion
(
int32_t
,
int
)
define_javaObjectRef_converion
(
int64_t
,
long
)
define_javaObjectRef_converion
(
char
,
byte
)
define_javaObjectRef_converion
(
float
,
float
)
define_javaObjectRef_converion
(
double
,
double
)
#endif
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
class
array_view
;
#define JAVA_ARRAY_CLASS_SPEC(ctype, type, Type) \
template <> class array_view<ctype> : public array_view_base<ctype> \
{ \
public: \
~array_view() { clear(); } \
array_view() {} \
array_view(const array<ctype>& arr, bool might_be_modified_=true){reset(JNI_GetEnv(),arr,might_be_modified_);} \
void reset(JNIEnv* jenv_, j##type##Array arr, bool might_be_modified_) { \
clear(); \
jenv = jenv_; \
oldArr = arr; \
if (arr) { \
pdata = (ctype*)jenv->Get##Type##ArrayElements(arr, 0); \
sz = jenv->GetArrayLength(arr); \
} \
might_be_modified = might_be_modified_; \
} \
private: \
void clear() { \
if (pdata) { \
jenv->Release##Type##ArrayElements(oldArr, (j##type*)pdata, might_be_modified?0:JNI_ABORT); \
pdata = nullptr; \
sz = 0; \
} \
} \
JNIEnv* jenv = nullptr; \
j##type##Array oldArr; \
bool might_be_modified; \
};
JAVA_ARRAY_CLASS_SPEC
(
int16_t
,
short
,
Short
)
JAVA_ARRAY_CLASS_SPEC
(
int32_t
,
int
,
Int
)
JAVA_ARRAY_CLASS_SPEC
(
int64_t
,
long
,
Long
)
JAVA_ARRAY_CLASS_SPEC
(
char
,
byte
,
Byte
)
JAVA_ARRAY_CLASS_SPEC
(
float
,
float
,
Float
)
JAVA_ARRAY_CLASS_SPEC
(
double
,
double
,
Double
)
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
T
,
typename
JARR
>
class
array_view_crit_base
{
public
:
array_view_crit_base
()
=
default
;
size_t
size
()
const
{
return
sz
;
}
T
*
data
()
{
return
pdata
;
}
const
T
*
data
()
const
{
return
pdata
;
}
T
*
begin
()
{
return
pdata
;
}
T
*
end
()
{
return
pdata
+
sz
;
}
const
T
*
begin
()
const
{
return
pdata
;
}
const
T
*
end
()
const
{
return
pdata
+
sz
;
}
T
&
operator
[](
size_t
i
)
{
return
pdata
[
i
];
}
const
T
&
operator
[](
size_t
i
)
const
{
return
pdata
[
i
];
}
~
array_view_crit_base
()
{
clear
();
}
void
reset
(
JNIEnv
*
jenv_
,
JARR
arr
,
bool
might_be_modified_
)
{
clear
();
jenv
=
jenv_
;
oldArr
=
arr
;
if
(
arr
)
{
pdata
=
(
T
*
)
jenv
->
GetPrimitiveArrayCritical
(
arr
,
0
);
sz
=
jenv
->
GetArrayLength
(
arr
);
}
might_be_modified
=
might_be_modified_
;
}
private
:
void
clear
()
{
if
(
pdata
)
{
jenv
->
ReleasePrimitiveArrayCritical
(
oldArr
,
pdata
,
might_be_modified
?
0
:
JNI_ABORT
);
pdata
=
nullptr
;
sz
=
0
;
}
}
// this object is non-copyable
array_view_crit_base
(
const
array_view_crit_base
&
);
array_view_crit_base
&
operator
=
(
const
array_view_crit_base
&
);
T
*
pdata
=
nullptr
;
size_t
sz
=
0
;
JNIEnv
*
jenv
=
nullptr
;
JARR
oldArr
;
bool
might_be_modified
;
};
template
<
typename
T
>
class
array_view_crit
;
template
<>
class
array_view_crit
<
int16_t
>
:
public
array_view_crit_base
<
int16_t
,
jshortArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
int16_t
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
template
<>
class
array_view_crit
<
int32_t
>
:
public
array_view_crit_base
<
int32_t
,
jintArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
int32_t
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
template
<>
class
array_view_crit
<
int64_t
>
:
public
array_view_crit_base
<
int64_t
,
jlongArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
int64_t
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
template
<>
class
array_view_crit
<
char
>
:
public
array_view_crit_base
<
char
,
jbyteArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
char
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
template
<>
class
array_view_crit
<
float
>
:
public
array_view_crit_base
<
float
,
jfloatArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
float
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
template
<>
class
array_view_crit
<
double
>
:
public
array_view_crit_base
<
double
,
jdoubleArray
>
{
public
:
array_view_crit
(){}
array_view_crit
(
const
array
<
double
>&
arr
,
bool
might_be_modified_
=
true
){
reset
(
JNI_GetEnv
(),
arr
,
might_be_modified_
);}
};
// ----------------------------------------------------------------------------------------
// Define SWIG typemaps so SWIG will know what to do with the array_view and array_view_crit
// objects.
#ifdef SWIG
%
define
define_array_converion
(
type
,
java_type
)
// Define array conversions for non-const arrays
%
typemap
(
jtype
)
(
array_view
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
array_view
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
array_view
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
array_view
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
array_view
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
array_view
<
type
>&
)
(
array_view
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
true
);
}
%
typemap
(
jtype
)
(
const
array_view
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
const
array_view
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
const
array_view
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
const
array_view
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
const
array_view
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
const
array_view
<
type
>&
)
(
array_view
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
false
);
}
%
enddef
define_array_converion
(
int16_t
,
short
)
define_array_converion
(
int32_t
,
int
)
define_array_converion
(
int64_t
,
long
)
define_array_converion
(
char
,
byte
)
define_array_converion
(
float
,
float
)
define_array_converion
(
double
,
double
)
%
define
define_array_crit_converion
(
type
,
java_type
)
// Define array conversions for non-const arrays
%
typemap
(
jtype
)
(
array_view_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
array_view_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
array_view_crit
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
array_view_crit
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
array_view_crit
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
array_view_crit
<
type
>&
)
(
array_view_crit
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
true
);
}
%
typemap
(
jtype
)
(
const
array_view_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
const
array_view_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
const
array_view_crit
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
const
array_view_crit
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
const
array_view_crit
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
const
array_view_crit
<
type
>&
)
(
array_view_crit
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
false
);
}
%
enddef
define_array_crit_converion
(
int16_t
,
short
)
define_array_crit_converion
(
int32_t
,
int
)
define_array_crit_converion
(
int64_t
,
long
)
define_array_crit_converion
(
char
,
byte
)
define_array_crit_converion
(
float
,
float
)
define_array_crit_converion
(
double
,
double
)
#endif // SWIG
}
#endif // DLIB_SWIG_JAVA_ARRAY_H_
dlib/java/jvector.h
deleted
100644 → 0
View file @
d9f93548
// Copyright (C) 2017 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SWIG_JVECTOR_H_
#define DLIB_SWIG_JVECTOR_H_
/*
This file defines two special classes, jvector and jvector_crit. Both of them have the
interface defined by jvector_base, that is, the interface of a simple array object like
std::vector (except without any ability to be resized). These classes are simple
interfaces to java native arrays. So for example, suppose you had an array of int in
java and you wanted to pass it to C++. You could create a C++ function like this:
void my_function(const jvector<int>& array);
and then within java you could call it with code like this:
int[] array = new int[100];
my_function(array);
and it will work just like you would expect. The jvector<int> will usually result in
the JVM doing a copy in the background. However, you can also declare your function
like this:
void my_function(const jvector_crit<int>& array);
and still call it the same way in java, however, using jvector_crit<int> will usually
not result in any copying, and is therefore very fast. jvector_crit uses the JNI
routine GetPrimitiveArrayCritical() to get a lock on the java memory underlying the
array. So it will probably prevent the garbage collector from running while your
function is executing. The JNI documentation is somewhat vague on the limitations of
GetPrimitiveArrayCritical(), saying only that you shouldn't hold the lock on the array
for "an extended period" or call back into the JVM. Deciding whether or not this
matters in your application is left as an exercise for the reader.
There are two ways you can declare your methods. Taking a const reference or a
non-const reference. E.g.:
void my_function(const jvector<int>& array);
void my_function(jvector<int>& array);
The non-const version allows you to modify the contents of the array and the
modifications will be visible to java, as you would expect.
You can also of course use functions taking many arguments, as is normally the case
with SWIG. Finally, jvector works with the following primitive types:
- int16_t
- int32_t
- int64_t
- char (corresponding to java byte)
- float
- double
*/
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
class
jvector_base
{
public
:
jvector_base
()
=
default
;
size_t
size
()
const
{
return
sz
;
}
T
*
data
()
{
return
pdata
;
}
const
T
*
data
()
const
{
return
pdata
;
}
T
*
begin
()
{
return
pdata
;
}
T
*
end
()
{
return
pdata
+
sz
;
}
const
T
*
begin
()
const
{
return
pdata
;
}
const
T
*
end
()
const
{
return
pdata
+
sz
;
}
T
&
operator
[](
size_t
i
)
{
return
pdata
[
i
];
}
const
T
&
operator
[](
size_t
i
)
const
{
return
pdata
[
i
];
}
protected
:
T
*
pdata
=
nullptr
;
size_t
sz
=
0
;
private
:
// this object is non-copyable
jvector_base
(
const
jvector_base
&
);
jvector_base
&
operator
=
(
const
jvector_base
&
);
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
class
jvector
;
#define JVECTOR_CLASS_SPEC(ctype, type, Type) \
template <> class jvector<ctype> : public jvector_base<ctype> \
{ \
public: \
~jvector() { clear(); } \
void reset(JNIEnv* jenv_, j##type##Array arr, bool mightBeModified_) { \
clear(); \
jenv = jenv_; \
oldArr = arr; \
pdata = (ctype*)jenv->Get##Type##ArrayElements(arr, 0); \
sz = jenv->GetArrayLength(arr); \
mightBeModified = mightBeModified_; \
} \
private: \
void clear() { \
if (pdata) { \
jenv->Release##Type##ArrayElements(oldArr, (j##type*)pdata, mightBeModified?0:JNI_ABORT); \
pdata = nullptr; \
} \
} \
JNIEnv* jenv = nullptr; \
j##type##Array oldArr; \
bool mightBeModified; \
};
JVECTOR_CLASS_SPEC
(
int16_t
,
short
,
Short
)
JVECTOR_CLASS_SPEC
(
int32_t
,
int
,
Int
)
JVECTOR_CLASS_SPEC
(
int64_t
,
long
,
Long
)
JVECTOR_CLASS_SPEC
(
char
,
byte
,
Byte
)
JVECTOR_CLASS_SPEC
(
float
,
float
,
Float
)
JVECTOR_CLASS_SPEC
(
double
,
double
,
Double
)
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
T
,
typename
JARR
>
class
jvector_crit_base
{
public
:
jvector_crit_base
()
=
default
;
size_t
size
()
const
{
return
sz
;
}
T
*
data
()
{
return
pdata
;
}
const
T
*
data
()
const
{
return
pdata
;
}
T
*
begin
()
{
return
pdata
;
}
T
*
end
()
{
return
pdata
+
sz
;
}
const
T
*
begin
()
const
{
return
pdata
;
}
const
T
*
end
()
const
{
return
pdata
+
sz
;
}
T
&
operator
[](
size_t
i
)
{
return
pdata
[
i
];
}
const
T
&
operator
[](
size_t
i
)
const
{
return
pdata
[
i
];
}
~
jvector_crit_base
()
{
clear
();
}
void
reset
(
JNIEnv
*
jenv_
,
JARR
arr
,
bool
mightBeModified_
)
{
clear
();
jenv
=
jenv_
;
oldArr
=
arr
;
pdata
=
(
T
*
)
jenv
->
GetPrimitiveArrayCritical
(
arr
,
0
);
sz
=
jenv
->
GetArrayLength
(
arr
);
mightBeModified
=
mightBeModified_
;
}
private
:
void
clear
()
{
if
(
pdata
)
{
jenv
->
ReleasePrimitiveArrayCritical
(
oldArr
,
pdata
,
mightBeModified
?
0
:
JNI_ABORT
);
pdata
=
nullptr
;
}
}
// this object is non-copyable
jvector_crit_base
(
const
jvector_crit_base
&
);
jvector_crit_base
&
operator
=
(
const
jvector_crit_base
&
);
T
*
pdata
=
nullptr
;
size_t
sz
=
0
;
JNIEnv
*
jenv
=
nullptr
;
JARR
oldArr
;
bool
mightBeModified
;
};
template
<
typename
T
>
class
jvector_crit
;
template
<>
class
jvector_crit
<
int16_t
>
:
public
jvector_crit_base
<
int16_t
,
jshortArray
>
{};
template
<>
class
jvector_crit
<
int32_t
>
:
public
jvector_crit_base
<
int32_t
,
jintArray
>
{};
template
<>
class
jvector_crit
<
int64_t
>
:
public
jvector_crit_base
<
int64_t
,
jlongArray
>
{};
template
<>
class
jvector_crit
<
char
>
:
public
jvector_crit_base
<
char
,
jbyteArray
>
{};
template
<>
class
jvector_crit
<
float
>
:
public
jvector_crit_base
<
float
,
jfloatArray
>
{};
template
<>
class
jvector_crit
<
double
>
:
public
jvector_crit_base
<
double
,
jdoubleArray
>
{};
// ----------------------------------------------------------------------------------------
// Define SWIG typemaps so SWIG will know what to do with the jvector and jvector_crit
// objects.
#ifdef SWIG
%
define
tostring
(
token
)
#token
%
enddef
%
define
define_jvector_converion
(
type
,
java_type
)
// Define array conversions for non-const arrays
%
typemap
(
jtype
)
(
jvector
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
jvector
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
jvector
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
jvector
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
jvector
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
jvector
<
type
>&
)
(
jvector
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
true
);
}
%
typemap
(
jtype
)
(
const
jvector
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
const
jvector
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
const
jvector
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
const
jvector
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
const
jvector
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
const
jvector
<
type
>&
)
(
jvector
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
false
);
}
%
enddef
define_jvector_converion
(
int16_t
,
short
)
define_jvector_converion
(
int32_t
,
int
)
define_jvector_converion
(
int64_t
,
long
)
define_jvector_converion
(
char
,
byte
)
define_jvector_converion
(
float
,
float
)
define_jvector_converion
(
double
,
double
)
%
define
define_jvector_crit_converion
(
type
,
java_type
)
// Define array conversions for non-const arrays
%
typemap
(
jtype
)
(
jvector_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
jvector_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
jvector_crit
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
jvector_crit
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
jvector_crit
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
jvector_crit
<
type
>&
)
(
jvector_crit
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
true
);
}
%
typemap
(
jtype
)
(
const
jvector_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jstype
)
(
const
jvector_crit
<
type
>&
)
"java_type[]"
%
typemap
(
jni
)
(
const
jvector_crit
<
type
>&
)
tostring
(
j
##
java_type
##
Array
)
%
typemap
(
javain
)
(
const
jvector_crit
<
type
>&
)
"$javainput"
%
typemap
(
arginit
)
(
const
jvector_crit
<
type
>&
)
{
$
1
=
&
temp
$
argnum
;
}
%
typemap
(
in
)
(
const
jvector_crit
<
type
>&
)
(
jvector_crit
<
type
>
temp
)
{
$
1
->
reset
(
jenv
,
$
input
,
false
);
}
%
enddef
define_jvector_crit_converion
(
int16_t
,
short
)
define_jvector_crit_converion
(
int32_t
,
int
)
define_jvector_crit_converion
(
int64_t
,
long
)
define_jvector_crit_converion
(
char
,
byte
)
define_jvector_crit_converion
(
float
,
float
)
define_jvector_crit_converion
(
double
,
double
)
#endif // SWIG
#endif // DLIB_SWIG_JVECTOR_H_
dlib/java/swig_api.h
View file @
af88b0d5
#ifndef EXAMPLE_SWIG_ApI_H_
#define EXAMPLE_SWIG_ApI_H_
// This file is essentially a small unit test for the swig cmake scripts and the j
vector
// This file is essentially a small unit test for the swig cmake scripts and the j
ava array
// classes. All it does it define a few simple functions for writing to and summing
// arrays. The swig_test.java file then calls these C++ functions and checks if they work
// correctly.
// Let's use the jvector, a tool for efficiently binding java native arrays to C++ function
// arguments. You do this by putting this pair of include statements in your swig_api.h
// file. Then after that you can use the jvector and jvector_crit classes.
#include "jvector.h"
// Let's use java_array.h, a tool for efficiently binding java native arrays to C++
// function arguments. You do this by putting this pair of include statements in your
// swig_api.h file. Then after that you can use the java::array, java::array_view, and
// java::array_view_crit classes.
#include "java_array.h"
#ifdef SWIG
%
include
"j
vector
.h"
%
include
"j
ava_array
.h"
#endif
// ----------------------------------------------------------------------------------------
using
namespace
java
;
// SWIG can't expose templated functions to java. We declare these here as helper
// functions to make the non-templated routines swig will expose easier to write. You can
// see these java exposed methods below (i.e. sum(), sum_crit(), assign(), and
// assign_crit()).
template
<
typename
T
>
T
tsum
(
const
jvector
_crit
<
T
>&
arr
)
T
tsum
(
const
array_view
_crit
<
T
>&
arr
)
{
T
s
=
0
;
for
(
auto
&
v
:
arr
)
...
...
@@ -32,7 +34,7 @@ T tsum(const jvector_crit<T>& arr)
return
s
;
}
template
<
typename
T
>
T
tsum
(
const
jvector
<
T
>&
arr
)
T
tsum
(
const
array_view
<
T
>&
arr
)
{
T
s
=
0
;
for
(
auto
&
v
:
arr
)
...
...
@@ -56,41 +58,64 @@ void tassign(T& arr)
// "global", which is where these sum and assign routines will appear. You can see
// examples of java code that calls them in swig_test.java.
inline
int
sum_crit
(
const
jvector_crit
<
int16_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
jvector
<
int16_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
int16_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
int16_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
array_view_crit
<
int16_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
array_view
<
int16_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
array_view_crit
<
int16_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array_view
<
int16_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
array_view_crit
<
int32_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
array_view
<
int32_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
array_view_crit
<
int32_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array_view
<
int32_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
array_view_crit
<
int64_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
array_view
<
int64_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
array_view_crit
<
int64_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array_view
<
int64_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
jvector_crit
<
int32_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
jvector
<
int32_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
int32_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
int32_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
array_view_crit
<
char
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
array_view
<
char
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
array_view_crit
<
char
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array_view
<
char
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
jvector_crit
<
int64_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
jvector
<
int64_t
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
int64_t
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
int64_t
>&
arr
)
{
tassign
(
arr
);
}
inline
int
sum_crit
(
const
jvector_crit
<
char
>&
arr
)
{
return
tsum
(
arr
);
}
inline
int
sum
(
const
jvector
<
char
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
char
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
char
>&
arr
)
{
tassign
(
arr
);
}
inline
double
sum_crit
(
const
array_view_crit
<
double
>&
arr
)
{
return
tsum
(
arr
);
}
inline
double
sum
(
const
array_view
<
double
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
array_view_crit
<
double
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array_view
<
double
>&
arr
)
{
tassign
(
arr
);
}
inline
float
sum_crit
(
array
<
float
>
arr
)
{
array_view_crit
<
float
>
a
(
arr
);
return
tsum
(
a
);
}
inline
float
sum
(
const
array
<
float
>&
arr
)
{
array_view
<
float
>
a
(
arr
);
return
tsum
(
a
);
}
inline
void
assign_crit
(
array_view_crit
<
float
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
array
<
float
>&
arr
)
{
array_view
<
float
>
a
(
arr
);
tassign
(
a
);
}
inline
double
sum_crit
(
const
jvector_crit
<
double
>&
arr
)
{
return
tsum
(
arr
);
}
inline
double
sum
(
const
jvector
<
double
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
double
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
double
>&
arr
)
{
tassign
(
arr
);
}
array
<
int32_t
>
make_an_array
(
size_t
s
)
{
array
<
int32_t
>
arr
(
s
);
array_view_crit
<
int32_t
>
a
(
arr
);
for
(
size_t
i
=
0
;
i
<
a
.
size
();
++
i
)
a
[
i
]
=
i
;
inline
float
sum_crit
(
const
jvector_crit
<
float
>&
arr
)
{
return
tsum
(
arr
);
}
inline
float
sum
(
const
jvector
<
float
>&
arr
)
{
return
tsum
(
arr
);
}
inline
void
assign_crit
(
jvector_crit
<
float
>&
arr
)
{
tassign
(
arr
);
}
inline
void
assign
(
jvector
<
float
>&
arr
)
{
tassign
(
arr
);
}
return
arr
;
}
// ----------------------------------------------------------------------------------------
...
...
dlib/java/swig_test.java
View file @
af88b0d5
...
...
@@ -69,6 +69,14 @@ public class swig_test
}
}
public
static
void
assertIsEqual
(
int
val1
,
int
val2
)
{
if
(
val1
!=
val2
)
{
throw
new
RuntimeException
(
"Test failed "
+
val1
+
" should be equal to "
+
val2
);
}
}
public
static
double
sum
(
double
[]
arr
)
{
double
s
=
0
;
...
...
@@ -233,6 +241,13 @@ public class swig_test
assertIs28
(
global
.
sum_crit
(
arr
));
}
}
{
int
[]
a
=
global
.
make_an_array
(
4
);
for
(
int
i
=
0
;
i
<
a
.
length
;
++
i
)
{
assertIsEqual
(
a
[
i
],
i
);
}
}
System
.
out
.
println
(
"\n\n ALL TESTS COMPLETED SUCCESSFULLY\n"
);
}
...
...
dlib/matrix/matrix_blas_bindings.h
View file @
af88b0d5
...
...
@@ -424,7 +424,7 @@ namespace dlib
template
<
typename
T
>
int
get_ld
(
const
matrix_op
<
op_pointer_to_col_vect
<
T
>
>&
m
)
{
return
m
.
nc
();
}
template
<
typename
T
>
int
get_ld
(
const
matrix_op
<
op_pointer_to_mat
<
T
>
>&
m
)
{
return
m
.
nc
()
;
}
int
get_ld
(
const
matrix_op
<
op_pointer_to_mat
<
T
>
>&
m
)
{
return
m
.
op
.
stride
;
}
// --------
...
...
@@ -443,7 +443,7 @@ namespace dlib
template
<
typename
T
>
int
get_inc
(
const
matrix_op
<
op_pointer_to_col_vect
<
T
>
>&
)
{
return
1
;
}
template
<
typename
T
>
int
get_inc
(
const
matrix_op
<
op_pointer_to_mat
<
T
>
>&
)
{
return
1
;
}
int
get_inc
(
const
matrix_op
<
op_pointer_to_mat
<
T
>
>&
m
)
{
return
m
.
op
.
stride
==
m
.
op
.
cols
?
1
:
0
;
}
template
<
typename
T
,
long
NR
,
long
NC
,
typename
MM
,
typename
L
>
int
get_inc
(
const
matrix
<
T
,
NR
,
NC
,
MM
,
L
>&
)
{
return
1
;
}
...
...
dlib/matrix/matrix_mat.h
View file @
af88b0d5
...
...
@@ -319,11 +319,19 @@ namespace dlib
const
T
*
ptr_
,
const
long
nr_
,
const
long
nc_
)
:
ptr
(
ptr_
),
rows
(
nr_
),
cols
(
nc_
){}
)
:
ptr
(
ptr_
),
rows
(
nr_
),
cols
(
nc_
),
stride
(
nc_
){}
op_pointer_to_mat
(
const
T
*
ptr_
,
const
long
nr_
,
const
long
nc_
,
const
long
stride_
)
:
ptr
(
ptr_
),
rows
(
nr_
),
cols
(
nc_
),
stride
(
stride_
){}
const
T
*
ptr
;
const
long
rows
;
const
long
cols
;
const
long
stride
;
const
static
long
cost
=
1
;
const
static
long
NR
=
0
;
...
...
@@ -333,7 +341,7 @@ namespace dlib
typedef
default_memory_manager
mem_manager_type
;
typedef
row_major_layout
layout_type
;
const_ret_type
apply
(
long
r
,
long
c
)
const
{
return
ptr
[
r
*
cols
+
c
];
}
const_ret_type
apply
(
long
r
,
long
c
)
const
{
return
ptr
[
r
*
stride
+
c
];
}
long
nr
()
const
{
return
rows
;
}
long
nc
()
const
{
return
cols
;
}
...
...
@@ -419,6 +427,27 @@ namespace dlib
return
matrix_op
<
op
>
(
op
(
ptr
,
nr
,
nc
));
}
template
<
typename
T
>
const
matrix_op
<
op_pointer_to_mat
<
T
>
>
mat
(
const
T
*
ptr
,
long
nr
,
long
nc
,
long
stride
)
{
DLIB_ASSERT
(
nr
>=
0
&&
nc
>=
0
&&
stride
>
0
,
"
\t
const matrix_exp mat(ptr, nr, nc, stride)"
<<
"
\n\t
nr and nc must be >= 0 while stride > 0"
<<
"
\n\t
nr: "
<<
nr
<<
"
\n\t
nc: "
<<
nc
<<
"
\n\t
stride: "
<<
stride
);
typedef
op_pointer_to_mat
<
T
>
op
;
return
matrix_op
<
op
>
(
op
(
ptr
,
nr
,
nc
,
stride
));
}
// ----------------------------------------------------------------------------------------
}
...
...
dlib/matrix/matrix_mat_abstract.h
View file @
af88b0d5
...
...
@@ -153,6 +153,35 @@ namespace dlib
the pointer and thus will not delete or free it.
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
const
matrix_exp
mat
(
const
T
*
ptr
,
long
nr
,
long
nc
,
long
stride
);
/*!
requires
- nr >= 0
- nc >= 0
- stride > 0
- ptr == a pointer to at least (nr-1)*stride+nc T objects (or the NULL pointer if nr*nc==0)
ensures
- returns a matrix M such that:
- M.nr() == nr
- m.nc() == nc
- for all valid r and c:
M(r,c) == ptr[r*stride + c]
(i.e. the pointer is interpreted as a matrix laid out in memory
in row major order, with a row stride of the given stride amount.)
- Note that the returned matrix doesn't take "ownership" of
the pointer and thus will not delete or free it.
!*/
// ----------------------------------------------------------------------------------------
template
<
...
...
dlib/test/dnn.cpp
View file @
af88b0d5
...
...
@@ -870,7 +870,7 @@ namespace
conv2
.
get_gradient_for_filters
(
true
,
gi
,
data
,
filter_gradient2
);
dlog
<<
LINFO
<<
"filter gradient error: "
<<
max
(
abs
(
mat
(
filter_gradient1
)
-
mat
(
filter_gradient2
)));
DLIB_TEST_MSG
(
max
(
abs
(
mat
(
filter_gradient1
)
-
mat
(
filter_gradient2
)))
<
1
e-3
,
max
(
abs
(
mat
(
filter_gradient1
)
-
mat
(
filter_gradient2
))));
DLIB_TEST_MSG
(
max
(
abs
(
mat
(
filter_gradient1
)
-
mat
(
filter_gradient2
)))
<
2
e-3
,
max
(
abs
(
mat
(
filter_gradient1
)
-
mat
(
filter_gradient2
))));
}
}
...
...
dlib/test/matrix.cpp
View file @
af88b0d5
...
...
@@ -1350,6 +1350,21 @@ namespace
DLIB_TEST
(
mm
(
3
)
==
4
);
}
{
const
long
n
=
5
;
matrix
<
double
>
m1
,
m2
,
m3
,
truth
;
m1
=
randm
(
n
,
n
);
m2
=
randm
(
n
,
n
);
rectangle
rect1
(
1
,
1
,
3
,
3
);
rectangle
rect2
(
2
,
1
,
4
,
3
);
truth
=
subm
(
m1
,
rect1
)
*
subm
(
m2
,
rect2
);
m3
=
mat
(
&
m1
(
0
,
0
)
+
6
,
3
,
3
,
m1
.
nc
())
*
mat
(
&
m2
(
0
,
0
)
+
7
,
3
,
3
,
m2
.
nc
());
DLIB_TEST
(
max
(
abs
(
truth
-
m3
))
<
1e-13
);
}
{
const
long
n
=
5
;
matrix
<
double
>
m1
,
m2
,
m3
,
truth
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment