Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
aml
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
27
Issues
27
List
Boards
Labels
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
argo
aml
Commits
8ba4dd1a
Commit
8ba4dd1a
authored
Sep 06, 2019
by
Brice Videau
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a thread single spinning thread engine for dma.
parent
09817b51
Pipeline
#8431
failed with stages
in 13 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
378 additions
and
0 deletions
+378
-0
include/Makefile.am
include/Makefile.am
+1
-0
include/aml/dma/linux-spin.h
include/aml/dma/linux-spin.h
+99
-0
src/Makefile.am
src/Makefile.am
+1
-0
src/dma/dma_linux_spin.c
src/dma/dma_linux_spin.c
+211
-0
tests/Makefile.am
tests/Makefile.am
+1
-0
tests/dma/test_dma_linux_spin.c
tests/dma/test_dma_linux_spin.c
+65
-0
No files found.
include/Makefile.am
View file @
8ba4dd1a
...
...
@@ -14,6 +14,7 @@ include_aml_layout_HEADERS = \
include_aml_dmadir
=
$(includedir)
/aml/dma
include_aml_dma_HEADERS
=
\
aml/dma/linux-seq.h
\
aml/dma/linux-spin.h
\
aml/dma/linux-par.h
include_aml_scratchdir
=
$(includedir)
/aml/scratch
...
...
include/aml/dma/linux-spin.h
0 → 100644
View file @
8ba4dd1a
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#ifndef AML_DMA_LINUX_SPIN_H
#define AML_DMA_LINUX_SPIN_H 1
/**
* @defgroup aml_dma_linux_spin "AML Parallel DMA"
* @brief Parallel DMA implementation.
*
* DMA logic implemented based on general linux API, asynchronous execution
* threads. This DMA implementation moves between pointers allocated with an
* aml_area_linux.
* @{
**/
/**
* Default table of dma request operations for linux
* parallel dma.
**/
extern
struct
aml_dma_ops
aml_dma_linux_spin_ops
;
/** Inside of a parallel request for linux movement. **/
struct
aml_dma_request_linux_spin
{
/**
* The type of dma request
* @see <aml.h>
**/
volatile
int
type
;
/** The destination pointer of the data movement **/
struct
aml_layout
*
dest
;
/** The source pointer of the data movement **/
struct
aml_layout
*
src
;
/** The dma containing sequential operations **/
struct
aml_dma_linux_spin
*
dma
;
/** The actual thread in charge for the request progress**/
pthread_t
thread
;
pthread_spinlock_t
lock
;
/** operator for this request **/
aml_dma_operator
op
;
/** operator argument for this request **/
void
*
op_arg
;
};
/** Inside of a parallel dma for linux movement. **/
struct
aml_dma_linux_spin_data
{
struct
aml_dma_request_linux_spin
req
;
/** default operator for this dma **/
aml_dma_operator
default_op
;
/** default operator arg for this dma **/
void
*
default_op_arg
;
};
/** Declaration of linux parallel dma operations **/
struct
aml_dma_linux_spin_ops
{
void
*
(
*
do_thread
)(
void
*
data
);
};
/**
* aml_dma structure for linux based, parallel dma movement
* Needs to be initialized with aml_dma_linux_spin_create().
* Can be passed to generic aml_dma_*() functions.
**/
struct
aml_dma_linux_spin
{
struct
aml_dma_linux_spin_ops
ops
;
struct
aml_dma_linux_spin_data
data
;
};
/**
* Allocates and initializes a new parallel DMA.
*
* @param dma an address where the pointer to the newly allocated DMA structure
* will be stored.
* @param nbreqs the initial number of slots for asynchronous requests that are
* in-flight (will be increased automatically if necessary).
* @param nbthreads the number of threads to launch for each request.
* @param op: default operator
* @return 0 if successful; an error code otherwise.
**/
int
aml_dma_linux_spin_create
(
struct
aml_dma
**
dma
,
aml_dma_operator
op
,
void
*
op_arg
);
/**
* Tears down a parallel DMA created with aml_dma_linux_spin_create.
* @param dma the address of a pointer to a parallel dma. Will be NULL after.
**/
void
aml_dma_linux_spin_destroy
(
struct
aml_dma
**
dma
);
/**
* @}
**/
#endif // AML_LINUX_DMA_LINUX_SPIN_H
src/Makefile.am
View file @
8ba4dd1a
...
...
@@ -19,6 +19,7 @@ LAYOUT_SOURCES = \
DMA_SOURCES
=
\
dma/dma.c
\
dma/dma_linux_par.c
\
dma/dma_linux_spin.c
\
dma/dma_linux_seq.c
TILING_SOURCES
=
\
...
...
src/dma/dma_linux_spin.c
0 → 100644
View file @
8ba4dd1a
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include "aml/dma/linux-spin.h"
#include "aml/layout/dense.h"
#include <assert.h>
#include <errno.h>
#include <sys/mman.h>
#define ASMPAUSE asm("" : : : "memory")
/*******************************************************************************
* Linux-backed, paruential dma
* The dma itself is organized into several different components
* - request types: copy
* - implementation of the request
* - user API (i.e. generic request creation and call)
* - how to init the dma
******************************************************************************/
/*******************************************************************************
* Requests:
******************************************************************************/
int
aml_dma_request_linux_spin_copy_init
(
struct
aml_dma_request_linux_spin
*
req
,
struct
aml_layout
*
dest
,
struct
aml_layout
*
src
,
aml_dma_operator
op
,
void
*
op_arg
)
{
assert
(
req
!=
NULL
);
req
->
type
=
AML_DMA_REQUEST_TYPE_LAYOUT
;
req
->
dest
=
dest
;
req
->
src
=
src
;
req
->
op
=
op
;
req
->
op_arg
=
op_arg
;
return
0
;
}
int
aml_dma_request_linux_spin_copy_destroy
(
struct
aml_dma_request_linux_spin
*
r
)
{
assert
(
r
!=
NULL
);
r
->
type
=
AML_DMA_REQUEST_TYPE_INVALID
;
return
0
;
}
/*******************************************************************************
* Internal functions
******************************************************************************/
void
*
aml_dma_linux_spin_do_thread
(
void
*
arg
)
{
struct
aml_dma_request_linux_spin
*
req
=
(
struct
aml_dma_request_linux_spin
*
)
arg
;
pthread_setcanceltype
(
PTHREAD_CANCEL_ASYNCHRONOUS
,
NULL
);
while
(
1
)
{
pthread_spin_lock
(
&
req
->
lock
);
if
(
req
->
type
!=
AML_DMA_REQUEST_TYPE_INVALID
)
{
req
->
op
(
req
->
dest
,
req
->
src
,
req
->
op_arg
);
req
->
type
=
AML_DMA_REQUEST_TYPE_INVALID
;
}
pthread_spin_unlock
(
&
req
->
lock
);
}
return
NULL
;
}
struct
aml_dma_linux_spin_ops
aml_dma_linux_spin_inner_ops
=
{
aml_dma_linux_spin_do_thread
,
};
/*******************************************************************************
* Public API
******************************************************************************/
int
aml_dma_linux_spin_create_request
(
struct
aml_dma_data
*
d
,
struct
aml_dma_request
**
r
,
struct
aml_layout
*
dest
,
struct
aml_layout
*
src
,
aml_dma_operator
op
,
void
*
op_arg
)
{
/* NULL checks done by the generic API */
assert
(
d
!=
NULL
);
assert
(
r
!=
NULL
);
assert
(
dest
!=
NULL
);
assert
(
src
!=
NULL
);
struct
aml_dma_linux_spin
*
dma
=
(
struct
aml_dma_linux_spin
*
)
d
;
struct
aml_dma_request_linux_spin
*
req
;
req
=
&
(
dma
->
data
.
req
);
if
(
op
==
NULL
)
op
=
dma
->
data
.
default_op
;
if
(
op_arg
==
NULL
)
op_arg
=
dma
->
data
.
default_op_arg
;
pthread_spin_lock
(
&
dma
->
data
.
req
.
lock
);
if
(
req
->
type
!=
AML_DMA_REQUEST_TYPE_INVALID
)
{
pthread_spin_unlock
(
&
dma
->
data
.
req
.
lock
);
return
-
AML_EINVAL
;
}
aml_dma_request_linux_spin_copy_init
(
req
,
dest
,
src
,
op
,
op_arg
);
pthread_spin_unlock
(
&
dma
->
data
.
req
.
lock
);
*
r
=
(
struct
aml_dma_request
*
)
req
;
return
0
;
}
int
aml_dma_linux_spin_destroy_request
(
struct
aml_dma_data
*
d
,
struct
aml_dma_request
**
r
)
{
return
0
;
}
int
aml_dma_linux_spin_wait_request
(
struct
aml_dma_data
*
d
,
struct
aml_dma_request
**
r
)
{
assert
(
d
!=
NULL
);
assert
(
r
!=
NULL
);
struct
aml_dma_linux_spin
*
dma
=
(
struct
aml_dma_linux_spin
*
)
d
;
struct
aml_dma_request_linux_spin
*
req
;
if
(
*
r
==
NULL
)
return
-
AML_EINVAL
;
req
=
(
struct
aml_dma_request_linux_spin
*
)
*
r
;
while
(
1
)
{
while
(
req
->
type
!=
AML_DMA_REQUEST_TYPE_INVALID
){
ASMPAUSE
;}
pthread_spin_lock
(
&
(
req
->
lock
));
//
if
(
req
->
type
==
AML_DMA_REQUEST_TYPE_INVALID
)
break
;
pthread_spin_unlock
(
&
(
req
->
lock
));
}
pthread_spin_unlock
(
&
(
req
->
lock
));
*
r
=
NULL
;
return
0
;
}
struct
aml_dma_ops
aml_dma_linux_spin_ops
=
{
aml_dma_linux_spin_create_request
,
aml_dma_linux_spin_destroy_request
,
aml_dma_linux_spin_wait_request
,
};
/*******************************************************************************
* Init functions:
******************************************************************************/
int
aml_dma_linux_spin_create
(
struct
aml_dma
**
dma
,
aml_dma_operator
op
,
void
*
op_arg
)
{
struct
aml_dma
*
ret
=
NULL
;
struct
aml_dma_linux_spin
*
d
;
if
(
dma
==
NULL
)
return
-
AML_EINVAL
;
*
dma
=
NULL
;
ret
=
AML_INNER_MALLOC_2
(
struct
aml_dma
,
struct
aml_dma_linux_spin
);
if
(
ret
==
NULL
)
return
-
AML_ENOMEM
;
ret
->
data
=
AML_INNER_MALLOC_NEXTPTR
(
ret
,
struct
aml_dma
,
struct
aml_dma_linux_spin
);
ret
->
ops
=
&
aml_dma_linux_spin_ops
;
d
=
(
struct
aml_dma_linux_spin
*
)
ret
->
data
;
d
->
ops
=
aml_dma_linux_spin_inner_ops
;
if
(
op
==
NULL
)
{
op
=
aml_copy_layout_generic
;
op_arg
=
NULL
;
}
d
->
data
.
default_op
=
op
;
d
->
data
.
default_op_arg
=
op_arg
;
/* allocate request array */
d
->
data
.
req
.
type
=
AML_DMA_REQUEST_TYPE_INVALID
;
pthread_spin_init
(
&
d
->
data
.
req
.
lock
,
PTHREAD_PROCESS_PRIVATE
);
pthread_create
(
&
d
->
data
.
req
.
thread
,
NULL
,
d
->
ops
.
do_thread
,
&
d
->
data
.
req
);
*
dma
=
ret
;
return
0
;
}
void
aml_dma_linux_spin_destroy
(
struct
aml_dma
**
d
)
{
struct
aml_dma_linux_spin
*
dma
;
if
(
d
==
NULL
||
*
d
==
NULL
)
return
;
dma
=
(
struct
aml_dma_linux_spin
*
)(
*
d
)
->
data
;
struct
aml_dma_request_linux_spin
*
req
;
req
=
&
dma
->
data
.
req
;
if
(
req
->
type
!=
AML_DMA_REQUEST_TYPE_INVALID
)
{
pthread_cancel
(
req
->
thread
);
pthread_join
(
req
->
thread
,
NULL
);
}
pthread_spin_destroy
(
&
req
->
lock
);
free
(
*
d
);
*
d
=
NULL
;
}
tests/Makefile.am
View file @
8ba4dd1a
...
...
@@ -23,6 +23,7 @@ LAYOUT_TESTS = layout/test_layout
TILING_TESTS
=
tiling/test_tiling
DMA_LINUX_TESTS
=
dma/test_dma_linux_seq
\
dma/test_dma_linux_spin
\
dma/test_dma_linux_par
if
RUN_CUDA
...
...
tests/dma/test_dma_linux_spin.c
0 → 100644
View file @
8ba4dd1a
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include "aml/layout/dense.h"
#include "aml/dma/linux-spin.h"
#include <assert.h>
int
main
(
int
argc
,
char
*
argv
[])
{
struct
aml_dma
*
dma
;
size_t
isz
=
1
<<
16
;
int
idest
[
isz
];
int
isrc
[
isz
];
struct
aml_layout
*
idl
,
*
isl
;
/* library initialization */
aml_init
(
&
argc
,
&
argv
);
/* support data structures */
assert
(
!
aml_layout_dense_create
(
&
idl
,
idest
,
0
,
sizeof
(
int
),
1
,
&
isz
,
NULL
,
NULL
));
assert
(
!
aml_layout_dense_create
(
&
isl
,
isrc
,
0
,
sizeof
(
int
),
1
,
&
isz
,
NULL
,
NULL
));
for
(
size_t
i
=
0
;
i
<
isz
;
i
++
)
{
idest
[
i
]
=
42
;
isrc
[
i
]
=
24
;
}
/* invalid create input */
assert
(
aml_dma_linux_spin_create
(
NULL
,
NULL
,
NULL
)
==
-
AML_EINVAL
);
/* invalid requests */
assert
(
!
aml_dma_linux_spin_create
(
&
dma
,
NULL
,
NULL
));
assert
(
aml_dma_copy
(
dma
,
NULL
,
isl
)
==
-
AML_EINVAL
);
assert
(
aml_dma_copy
(
dma
,
idl
,
NULL
)
==
-
AML_EINVAL
);
struct
aml_dma_request
*
r1
,
*
r2
;
/* force dma to increase its requests queue */
assert
(
!
aml_dma_async_copy
(
dma
,
&
r1
,
idl
,
isl
));
assert
(
!
aml_dma_wait
(
dma
,
&
r1
));
assert
(
!
aml_dma_async_copy
(
dma
,
&
r2
,
idl
,
isl
));
assert
(
aml_dma_wait
(
dma
,
NULL
)
==
-
AML_EINVAL
);
assert
(
!
aml_dma_wait
(
dma
,
&
r2
));
assert
(
!
memcmp
(
isrc
,
idest
,
isz
*
sizeof
(
int
)));
aml_dma_linux_spin_destroy
(
&
dma
);
/* destroy a running dma */
assert
(
!
aml_dma_linux_spin_create
(
&
dma
,
NULL
,
NULL
));
assert
(
!
aml_dma_async_copy
(
dma
,
&
r1
,
idl
,
isl
));
aml_dma_linux_spin_destroy
(
&
dma
);
/* delete everything */
aml_layout_dense_destroy
(
&
idl
);
aml_layout_dense_destroy
(
&
isl
);
aml_finalize
();
return
0
;
}
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