Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
9.2.2023: Due to updates GitLab will be unavailable for some minutes between 9:00 and 11:00.
Open sidebar
CAMP
campvis-public
Commits
d281e78e
Commit
d281e78e
authored
Dec 13, 2013
by
Christian Schulte zu Berge
Browse files
closes Issue #42: Completely removed ViennaCL dependency from RandomWalksLib.
parent
9fe8a51f
Changes
207
Expand all
Hide whitespace changes
Inline
Side-by-side
modules/randomwalk/ext/RandomWalksLib/CMakeLists.txt
View file @
d281e78e
...
...
@@ -33,29 +33,13 @@ SET(RandomWalksLibSources ConfidenceMaps2D.cpp
SparseSolverEigenLLT.cpp
SparseSolverFactory.cpp
)
# Make OpenCL dependency optional
IF
(
OPENCL_FOUND
)
ADD_DEFINITIONS
(
"-DRANDOMWALKSLIB_HAS_OPENCL"
)
LIST
(
APPEND RandomWalksLibExternalLibs
${
OPENCL_LIBRARY
}
)
LIST
(
APPEND RandomWalksLibHeaders SparseSolverViennaCPU.h SparseSolverViennaGPU.h
)
LIST
(
APPEND RandomWalksLibSources SparseSolverViennaCPU.cpp SparseSolverViennaGPU.cpp
)
ENDIF
()
################################################################################
# define library target
################################################################################
# Eigen RandomWalksLibHeaders are already in CAMPVis/ext
INCLUDE_DIRECTORIES
(
${
CampvisGlobalIncludeDirs
}
)
#include ViennaCl RandomWalksLibHeaders
INCLUDE_DIRECTORIES
(
${
CMAKE_CURRENT_SOURCE_DIR
}
)
ADD_LIBRARY
(
RandomWalksLib STATIC
${
RandomWalksLibSources
}
${
RandomWalksLibHeaders
}
)
# We don't want this within CAMPVis...
#put debug target to x64/Debug and all other configurations to x64/Release
#SET_TARGET_PROPERTIES( RandomWalksLib PROPERTIES
# ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/x64/Release #static libs are archives
# ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/x64/Debug
# ARCHIVE_OUTPUT_NAME RandomWalksLib
# ARCHIVE_OUTPUT_NAME_DEBUG RandomWalksLibd ) #debug build should end with a 'd'
TARGET_LINK_LIBRARIES
(
RandomWalksLib
${
RandomWalksLibExternalLibs
}
)
modules/randomwalk/ext/RandomWalksLib/SparseSolverFactory.cpp
View file @
d281e78e
...
...
@@ -35,18 +35,6 @@ SparseSolverInterface * SparseSolverFactory::createSolver(std::string type, int
SparseSolverInterface
*
solver
=
new
SparseSolverEigenCustom
(
iterations
,
tolerance
);
return
solver
;
}
#ifdef RANDOMWALKSLIB_HAS_OPENCL
else
if
(
type
.
compare
(
"Vienna-CG-CPU"
)
==
0
)
{
SparseSolverInterface
*
solver
=
new
SparseSolverViennaCPU
(
iterations
,
tolerance
);
return
solver
;
}
else
if
(
type
.
compare
(
"Vienna-CG-GPU"
)
==
0
)
{
SparseSolverInterface
*
solver
=
new
SparseSolverViennaGPU
(
iterations
,
tolerance
);
return
solver
;
}
#endif
else
{
return
new
SparseSolverEigenLLT
();
...
...
modules/randomwalk/ext/RandomWalksLib/SparseSolverViennaCPU.cpp
deleted
100644 → 0
View file @
9fe8a51f
#include
"SparseSolverViennaCPU.h"
#define VIENNACL_HAVE_EIGEN
#include
<viennacl\scalar.hpp>
#include
<viennacl\matrix.hpp>
#include
<viennacl\compressed_matrix.hpp>
#include
<viennacl\linalg\cg.hpp>
SparseSolverViennaCPU
::
SparseSolverViennaCPU
(
int
iterations
,
double
tolerance
)
{
this
->
iterations
=
iterations
;
this
->
tolerance
=
tolerance
;
}
std
::
vector
<
double
>
SparseSolverViennaCPU
::
solve_Ax_b
(
SparseMatrix
<
double
>
A
,
SparseVector
<
double
>
b
,
int
numel
,
std
::
vector
<
int
>
&
uidx
,
const
std
::
vector
<
int
>
*
labels
,
const
std
::
vector
<
int
>
*
seeds
,
int
active_label
)
{
SparseMatrix
<
double
>
A_sparse_matrix
(
A
);
VectorXd
b_dense
=
b
;
viennacl
::
linalg
::
cg_tag
custom_tag
(
tolerance
,
iterations
);
VectorXd
x_dense
=
viennacl
::
linalg
::
solve
(
A_sparse_matrix
,
b_dense
,
custom_tag
);
// CPU Solver with dense
std
::
vector
<
double
>
xmat
(
numel
);
for
(
int
i
=
0
;
i
<
x_dense
.
rows
();
i
++
)
{
xmat
[
uidx
[
i
]]
=
x_dense
(
i
);
}
for
(
size_t
i
=
0
;
i
<
seeds
->
size
();
i
++
)
{
if
((
*
labels
)[
i
]
==
active_label
)
xmat
[(
*
seeds
)[
i
]]
=
1.0
;
else
xmat
[(
*
seeds
)[
i
]]
=
0.0
;
}
return
xmat
;
}
\ No newline at end of file
modules/randomwalk/ext/RandomWalksLib/SparseSolverViennaCPU.h
deleted
100644 → 0
View file @
9fe8a51f
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SPARSE_SOLVER_VIENNA_CPU_H__
#define SPARSE_SOLVER_VIENNA_CPU_H__
#include
"SparseSolverInterface.h"
/** \brief Conjugate Gradient Vienna solver on CPU for random walks system
* \author Athanasios Karamalis
* \date 11.06.2012
*/
class
SparseSolverViennaCPU
:
public
SparseSolverInterface
{
public:
SparseSolverViennaCPU
(
int
iterations
,
double
tolerance
);
/// Solver with CG
virtual
std
::
vector
<
double
>
solve_Ax_b
(
SparseMatrix
<
double
>
A
,
SparseVector
<
double
>
b
,
int
numel
,
std
::
vector
<
int
>
&
uidx
,
const
std
::
vector
<
int
>
*
labels
,
const
std
::
vector
<
int
>
*
seeds
,
int
active_label
);
private:
int
iterations
;
///< CG iterations
double
tolerance
;
///< CG tolerance
};
#endif
\ No newline at end of file
modules/randomwalk/ext/RandomWalksLib/SparseSolverViennaGPU.cpp
deleted
100644 → 0
View file @
9fe8a51f
#include
"SparseSolverViennaGPU.h"
#define VIENNACL_HAVE_EIGEN
#include
<viennacl\scalar.hpp>
#include
<viennacl\matrix.hpp>
#include
<viennacl\compressed_matrix.hpp>
#include
<viennacl\linalg\cg.hpp>
SparseSolverViennaGPU
::
SparseSolverViennaGPU
(
int
iterations
,
double
tolerance
)
{
this
->
iterations
=
iterations
;
this
->
tolerance
=
tolerance
;
}
std
::
vector
<
double
>
SparseSolverViennaGPU
::
solve_Ax_b
(
SparseMatrix
<
double
>
A
,
SparseVector
<
double
>
b
,
int
numel
,
std
::
vector
<
int
>
&
uidx
,
const
std
::
vector
<
int
>
*
labels
,
const
std
::
vector
<
int
>
*
seeds
,
int
active_label
)
{
SparseMatrix
<
double
>
A_sparse_matrix
(
A
);
VectorXd
b_dense
=
b
;
viennacl
::
linalg
::
cg_tag
custom_tag
(
tolerance
,
iterations
);
viennacl
::
compressed_matrix
<
double
>
viennacl_A
(
A_sparse_matrix
.
rows
(),
A_sparse_matrix
.
cols
());
viennacl
::
vector
<
double
>
viennacl_b
(
b_dense
.
rows
());
viennacl
::
vector
<
double
>
viennacl_x
(
b_dense
.
rows
());
viennacl
::
copy
(
A_sparse_matrix
,
viennacl_A
);
viennacl
::
copy
(
b_dense
,
viennacl_b
);
viennacl_x
=
viennacl
::
linalg
::
solve
(
viennacl_A
,
viennacl_b
,
custom_tag
);
// GPU Solver
VectorXd
x_dense
(
b
.
rows
());
viennacl
::
copy
(
viennacl_x
,
x_dense
);
std
::
vector
<
double
>
xmat
(
numel
);
for
(
int
i
=
0
;
i
<
x_dense
.
rows
();
i
++
)
{
xmat
[
uidx
[
i
]]
=
x_dense
(
i
);
}
for
(
size_t
i
=
0
;
i
<
seeds
->
size
();
i
++
)
{
if
((
*
labels
)[
i
]
==
active_label
)
xmat
[(
*
seeds
)[
i
]]
=
1.0
;
else
xmat
[(
*
seeds
)[
i
]]
=
0.0
;
}
return
xmat
;
}
\ No newline at end of file
modules/randomwalk/ext/RandomWalksLib/SparseSolverViennaGPU.h
deleted
100644 → 0
View file @
9fe8a51f
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SPRASE_SOLVER_VIENNA_GPU_H__
#define SPRASE_SOLVER_VIENNA_GPU_H__
#include
"SparseSolverInterface.h"
/** \brief Conjugate Gradient Vienna solver on GPU for random walks system
* \author Athanasios Karamalis
* \date 11.06.2012
*/
class
SparseSolverViennaGPU
:
public
SparseSolverInterface
{
public:
SparseSolverViennaGPU
(
int
iterations
,
double
tolerance
);
/// Solver with CG
virtual
std
::
vector
<
double
>
solve_Ax_b
(
SparseMatrix
<
double
>
A
,
SparseVector
<
double
>
b
,
int
numel
,
std
::
vector
<
int
>
&
uidx
,
const
std
::
vector
<
int
>
*
labels
,
const
std
::
vector
<
int
>
*
seeds
,
int
active_label
);
private:
int
iterations
;
///< CG iterations
double
tolerance
;
///< CG tolerance
};
#endif
\ No newline at end of file
modules/randomwalk/ext/RandomWalksLib/viennacl/backend/cpu_ram.hpp
deleted
100644 → 0
View file @
9fe8a51f
#ifndef VIENNACL_BACKEND_CPU_RAM_HPP_
#define VIENNACL_BACKEND_CPU_RAM_HPP_
/* =========================================================================
Copyright (c) 2010-2012, Institute for Microelectronics,
Institute for Analysis and Scientific Computing,
TU Wien.
Portions of this software are copyright by UChicago Argonne, LLC.
-----------------
ViennaCL - The Vienna Computing Library
-----------------
Project Head: Karl Rupp rupp@iue.tuwien.ac.at
(A list of authors and contributors can be found in the PDF manual)
License: MIT (X11), see file LICENSE in the base directory
============================================================================= */
/** @file viennacl/backend/cpu_ram.hpp
@brief Implementations for the OpenCL backend functionality
*/
#include
<vector>
#include
"viennacl/tools/shared_ptr.hpp"
namespace
viennacl
{
namespace
backend
{
namespace
cpu_ram
{
typedef
viennacl
::
tools
::
shared_ptr
<
char
>
handle_type
;
// Requirements for backend:
// * memory_create(size, host_ptr)
// * memory_copy(src, dest, offset_src, offset_dest, size)
// * memory_write_from_main_memory(src, offset, size,
// dest, offset, size)
// * memory_read_to_main_memory(src, offset, size
// dest, offset, size)
// *
//
namespace
detail
{
template
<
class
U
>
struct
array_deleter
{
void
operator
()(
U
*
p
)
const
{
delete
[]
p
;
}
};
}
inline
handle_type
memory_create
(
std
::
size_t
size_in_bytes
,
const
void
*
host_ptr
=
NULL
)
{
if
(
!
host_ptr
)
return
handle_type
(
new
char
[
size_in_bytes
],
detail
::
array_deleter
<
char
>
());
handle_type
new_handle
(
new
char
[
size_in_bytes
],
detail
::
array_deleter
<
char
>
());
// copy data:
char
*
raw_ptr
=
new_handle
.
get
();
const
char
*
data_ptr
=
static_cast
<
const
char
*>
(
host_ptr
);
for
(
std
::
size_t
i
=
0
;
i
<
size_in_bytes
;
++
i
)
raw_ptr
[
i
]
=
data_ptr
[
i
];
return
new_handle
;
}
inline
void
memory_copy
(
handle_type
const
&
src_buffer
,
handle_type
&
dst_buffer
,
std
::
size_t
src_offset
,
std
::
size_t
dst_offset
,
std
::
size_t
bytes_to_copy
)
{
assert
(
(
dst_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
assert
(
(
src_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
for
(
std
::
size_t
i
=
0
;
i
<
bytes_to_copy
;
++
i
)
dst_buffer
.
get
()[
i
+
dst_offset
]
=
src_buffer
.
get
()[
i
+
src_offset
];
}
inline
void
memory_write
(
handle_type
&
dst_buffer
,
std
::
size_t
dst_offset
,
std
::
size_t
bytes_to_copy
,
const
void
*
ptr
)
{
assert
(
(
dst_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
for
(
std
::
size_t
i
=
0
;
i
<
bytes_to_copy
;
++
i
)
dst_buffer
.
get
()[
i
+
dst_offset
]
=
static_cast
<
const
char
*>
(
ptr
)[
i
];
}
inline
void
memory_read
(
handle_type
const
&
src_buffer
,
std
::
size_t
src_offset
,
std
::
size_t
bytes_to_copy
,
void
*
ptr
)
{
assert
(
(
src_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
for
(
std
::
size_t
i
=
0
;
i
<
bytes_to_copy
;
++
i
)
static_cast
<
char
*>
(
ptr
)[
i
]
=
src_buffer
.
get
()[
i
+
src_offset
];
}
}
}
//backend
}
//viennacl
#endif
modules/randomwalk/ext/RandomWalksLib/viennacl/backend/cuda.hpp
deleted
100644 → 0
View file @
9fe8a51f
#ifndef VIENNACL_BACKEND_CUDA_HPP_
#define VIENNACL_BACKEND_CUDA_HPP_
/* =========================================================================
Copyright (c) 2010-2012, Institute for Microelectronics,
Institute for Analysis and Scientific Computing,
TU Wien.
Portions of this software are copyright by UChicago Argonne, LLC.
-----------------
ViennaCL - The Vienna Computing Library
-----------------
Project Head: Karl Rupp rupp@iue.tuwien.ac.at
(A list of authors and contributors can be found in the PDF manual)
License: MIT (X11), see file LICENSE in the base directory
============================================================================= */
/** @file viennacl/backend/cuda.hpp
@brief Implementations for the CUDA backend functionality
*/
#include
<iostream>
#include
<vector>
#include
"viennacl/tools/shared_ptr.hpp"
// includes CUDA
#include
<cuda_runtime.h>
#define VIENNACL_CUDA_ERROR_CHECK(err) detail::cuda_error_check (err, __FILE__, __LINE__)
namespace
viennacl
{
namespace
backend
{
namespace
cuda
{
typedef
viennacl
::
tools
::
shared_ptr
<
char
>
handle_type
;
// Requirements for backend:
// * memory_create(size, host_ptr)
// * memory_copy(src, dest, offset_src, offset_dest, size)
// * memory_write_from_main_memory(src, offset, size,
// dest, offset, size)
// * memory_read_to_main_memory(src, offset, size
// dest, offset, size)
// *
//
namespace
detail
{
inline
void
cuda_error_check
(
cudaError
error_code
,
const
char
*
file
,
const
int
line
)
{
if
(
cudaSuccess
!=
error_code
)
{
std
::
cerr
<<
file
<<
"("
<<
line
<<
"): "
<<
": CUDA Runtime API error "
<<
error_code
<<
": "
<<
cudaGetErrorString
(
error_code
)
<<
std
::
endl
;
throw
"CUDA error"
;
}
}
template
<
typename
U
>
struct
cuda_deleter
{
void
operator
()(
U
*
p
)
const
{
//std::cout << "Freeing handle " << reinterpret_cast<void *>(p) << std::endl;
cudaFree
(
p
);
}
};
}
inline
handle_type
memory_create
(
std
::
size_t
size_in_bytes
,
const
void
*
host_ptr
=
NULL
)
{
void
*
dev_ptr
=
NULL
;
VIENNACL_CUDA_ERROR_CHECK
(
cudaMalloc
(
&
dev_ptr
,
size_in_bytes
)
);
//std::cout << "Allocated new dev_ptr " << dev_ptr << " of size " << size_in_bytes << std::endl;
if
(
!
host_ptr
)
return
handle_type
(
reinterpret_cast
<
char
*>
(
dev_ptr
),
detail
::
cuda_deleter
<
char
>
());
handle_type
new_handle
(
reinterpret_cast
<
char
*>
(
dev_ptr
),
detail
::
cuda_deleter
<
char
>
());
// copy data:
//std::cout << "Filling new handle from host_ptr " << host_ptr << std::endl;
cudaMemcpy
(
new_handle
.
get
(),
host_ptr
,
size_in_bytes
,
cudaMemcpyHostToDevice
);
return
new_handle
;
}
inline
void
memory_copy
(
handle_type
const
&
src_buffer
,
handle_type
&
dst_buffer
,
std
::
size_t
src_offset
,
std
::
size_t
dst_offset
,
std
::
size_t
bytes_to_copy
)
{
assert
(
(
dst_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
assert
(
(
src_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
cudaMemcpy
(
reinterpret_cast
<
void
*>
(
dst_buffer
.
get
()
+
dst_offset
),
reinterpret_cast
<
void
*>
(
src_buffer
.
get
()
+
src_offset
),
bytes_to_copy
,
cudaMemcpyDeviceToDevice
);
}
inline
void
memory_write
(
handle_type
&
dst_buffer
,
std
::
size_t
dst_offset
,
std
::
size_t
bytes_to_copy
,
const
void
*
ptr
)
{
assert
(
(
dst_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
cudaMemcpy
(
reinterpret_cast
<
char
*>
(
dst_buffer
.
get
())
+
dst_offset
,
reinterpret_cast
<
const
char
*>
(
ptr
),
bytes_to_copy
,
cudaMemcpyHostToDevice
);
}
inline
void
memory_read
(
handle_type
const
&
src_buffer
,
std
::
size_t
src_offset
,
std
::
size_t
bytes_to_copy
,
void
*
ptr
)
{
assert
(
(
src_buffer
.
get
()
!=
NULL
)
&&
bool
(
"Memory not initialized!"
));
cudaMemcpy
(
reinterpret_cast
<
char
*>
(
ptr
),
reinterpret_cast
<
char
*>
(
src_buffer
.
get
())
+
src_offset
,
bytes_to_copy
,
cudaMemcpyDeviceToHost
);
}
}
//cuda
}
//backend
}
//viennacl
#endif
modules/randomwalk/ext/RandomWalksLib/viennacl/backend/mem_handle.hpp
deleted
100644 → 0
View file @
9fe8a51f
#ifndef VIENNACL_BACKEND_MEM_HANDLE_HPP
#define VIENNACL_BACKEND_MEM_HANDLE_HPP
/* =========================================================================
Copyright (c) 2010-2012, Institute for Microelectronics,
Institute for Analysis and Scientific Computing,
TU Wien.
Portions of this software are copyright by UChicago Argonne, LLC.
-----------------
ViennaCL - The Vienna Computing Library
-----------------
Project Head: Karl Rupp rupp@iue.tuwien.ac.at
(A list of authors and contributors can be found in the PDF manual)
License: MIT (X11), see file LICENSE in the base directory
============================================================================= */
/** @file viennacl/backend/mem_handle.hpp
@brief Implements the multi-memory-domain handle
*/
#include
<vector>
#include
<cassert>
#include
"viennacl/forwards.h"
#include
"viennacl/tools/shared_ptr.hpp"
#include
"viennacl/backend/cpu_ram.hpp"
#ifdef VIENNACL_WITH_OPENCL
#include
"viennacl/backend/opencl.hpp"
#endif
#ifdef VIENNACL_WITH_CUDA
#include
"viennacl/backend/cuda.hpp"
#endif
namespace
viennacl
{
namespace
backend
{
// if a user compiles with CUDA, it is reasonable to expect that CUDA should be the default
#ifdef VIENNACL_WITH_CUDA
inline
memory_types
default_memory_type
()
{
return
CUDA_MEMORY
;
}
#elif defined(VIENNACL_WITH_OPENCL)
inline
memory_types
default_memory_type
()
{
return
OPENCL_MEMORY
;
}
#else
inline
memory_types
default_memory_type
()
{
return
MAIN_MEMORY
;
}
#endif
class
mem_handle
{
public:
typedef
viennacl
::
tools
::
shared_ptr
<
char
>
ram_handle_type
;
typedef
viennacl
::
tools
::
shared_ptr
<
char
>
cuda_handle_type
;
mem_handle
()
:
active_handle_
(
MEMORY_NOT_INITIALIZED
),
size_in_bytes_
(
0
)
{}
ram_handle_type
&
ram_handle
()
{
return
ram_handle_
;
}
ram_handle_type
const
&
ram_handle
()
const
{
return
ram_handle_
;
}
#ifdef VIENNACL_WITH_OPENCL
viennacl
::
ocl
::
handle
<
cl_mem
>
&
opencl_handle
()
{
return
opencl_handle_
;
}
viennacl
::
ocl
::
handle
<
cl_mem
>
const
&
opencl_handle
()
const
{
return
opencl_handle_
;
}
#endif
#ifdef VIENNACL_WITH_CUDA
cuda_handle_type
&
cuda_handle
()
{
return
cuda_handle_
;
}
cuda_handle_type
const
&
cuda_handle
()
const
{
return
cuda_handle_
;
}
#endif
memory_types
get_active_handle_id
()
const
{
return
active_handle_
;
}
void
switch_active_handle_id
(
memory_types
new_id
)
{
if
(
new_id
!=
active_handle_
)
{
if
(
active_handle_
==
MEMORY_NOT_INITIALIZED
)
active_handle_
=
new_id
;
else
if
(
active_handle_
==
MAIN_MEMORY
)
{
active_handle_
=
new_id
;
}
else
if
(
active_handle_
==
OPENCL_MEMORY
)
{
#ifdef VIENNACL_WITH_OPENCL
active_handle_
=
new_id
;
#else
throw
"compiled without OpenCL suppport!"
;
#endif
}
else
if
(
active_handle_
==
CUDA_MEMORY
)
{
#ifdef VIENNACL_WITH_CUDA
active_handle_
=
new_id
;
#else
throw
"compiled without CUDA suppport!"
;
#endif
}
else
throw
"invalid new memory region!"
;
}
}
bool
operator
==
(
mem_handle
const
&
other
)
const
{
if
(
active_handle_
!=
other
.
active_handle_
)
return
false
;
switch
(
active_handle_
)
{
case
MAIN_MEMORY
:
return
ram_handle_
.
get
()
==
other
.
ram_handle_
.
get
();
#ifdef VIENNACL_WITH_OPENCL
case
OPENCL_MEMORY
:
return
opencl_handle_
.
get
()
==
other
.
opencl_handle_
.
get
();
#endif
#ifdef VIENNACL_WITH_CUDA
case
CUDA_MEMORY
:
return
cuda_handle_
.
get
()
==
other
.
cuda_handle_
.
get
();
#endif
default:
break
;
}