diff --git a/src/include/ablas.h b/src/include/ablas.h index eccf60d13..f8512f78c 100644 --- a/src/include/ablas.h +++ b/src/include/ablas.h @@ -1,17 +1,6 @@ /* ************************************************************************ - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. * ************************************************************************ */ /*!\file @@ -24,9 +13,11 @@ #define _ABLAS_H_ #include +#include "ablas_hip.h" +#include "ablas_runtime.h" + #include "ablas_types.h" -#include "ablas_common" #include "ablas_netlib.h" #include "ablas_netlib_batched.h" #include "ablas_export.h" diff --git a/src/include/ablas_common.h b/src/include/ablas_common.h new file mode 100644 index 000000000..bb6241e12 --- /dev/null +++ b/src/include/ablas_common.h @@ -0,0 +1,40 @@ +/* ************************************************************************ + * Copyright 2016 Advanced Micro Devices, Inc. + * + * ************************************************************************ */ + +#pragma once +#ifndef _ABLAS_COMMON_H_ +#define _ABLAS_COMMON_H_ + +#include "ablas_types.h" + + +/*!\file + * \brief provide some common integer operations. + */ + + + /* ============================================================================================ */ + /* integer functions */ + + /*! \brief For integers x >= 0, y > 0, returns ceil( x/y ). + * For x == 0, this is 0. + */ + __host__ __device__ + static inline ablas_int ablas_ceildiv( ablas_int x, ablas_int y ) + { + return (x + y - 1)/y; + } + + /*! \brief For integers x >= 0, y > 0, returns x rounded up to multiple of y. + * For x == 0, this is 0. y is not necessarily a power of 2. + */ + __host__ __device__ + static inline ablas_int ablas_roundup( ablas_int x, ablas_int y ) + { + return ablas_ceildiv( x, y ) * y; + } + + +#endif diff --git a/src/include/ablas_expert.h b/src/include/ablas_expert.h index 4953903e3..42195ff2a 100644 --- a/src/include/ablas_expert.h +++ b/src/include/ablas_expert.h @@ -1,17 +1,6 @@ /* ************************************************************************ - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. * ************************************************************************ */ /*! \file diff --git a/src/include/ablas_hip.h b/src/include/ablas_hip.h new file mode 100644 index 000000000..8c673d40c --- /dev/null +++ b/src/include/ablas_hip.h @@ -0,0 +1,81 @@ +/* ************************************************************************ + * Copyright 2016 Advanced Micro Devices, Inc. + * + * ************************************************************************ */ + +#pragma once +#ifndef _ABLAS_HIP_H_ +#define _ABLAS_HIP_H_ + +#include + +/*!\file + * \brief ABLAS interface with HIP APIs: memory allocation, device management + */ + + +typedef hipStream_t ablas_queue; +typedef hipEvent_t ablas_event; +typedef ablas_queue ablas_handle; + + + /* ============================================================================================ */ + /** + * @brief ablas error codes definition, incorporating HIP error + * definitions. + * + * This enumeration is a subset of the HIP error codes extended with some + * additional extra codes. For example, hipErrorMemoryAllocation, which is + * defined in hip_runtime_api.h is aliased as ablas_error_memory_allocation. + */ + typedef enum ablas_status_ { + + ablas_success = hipSuccess = 0, ///< Successful completion. + ablas_error_memory_allocation = hipErrorMemoryAllocation, ///< Memory allocation error. + ablas_error_memory_free = hipErrorMemoryFree, ///< Memory free error. + ablas_error_unknown_symbol = hipErrorUnknownSymbol, ///< Unknown symbol + ablas_error_outof_resources = hipErrorOutOfResources ///< Out of resources error + ablas_error_invalid_value = hipErrorInvalidValue ///< One or more of the paramters passed to the API call is NULL or not in an acceptable range. + ablas_error_invalid_resource_handle = hipErrorInvalidResourceHandle ///< Resource handle (hipEvent_t or hipStream_t) invalid. + ablas_error_invalid_device = hipErrorInvalidDevice ///< DeviceID must be in range 0...#compute-devices. + ablas_error_no_deive = hipErrorNoDevice ///< Call to cudaGetDeviceCount returned 0 devices + ablas_error_not_ready = hipErrorNotReady ///< indicates that asynchronous operations enqueued earlier are not ready. + /// This is not actually an error, but is used to distinguish from hipSuccess(which indicates completion). + /// APIs that return this error include hipEventQuery and hipStreamQuery. + /* Extended error codes */ + ablas_not_implemented = -1024, /**< Functionality is not implemented */ + ablas_not_initialized, /**< ablas library is not initialized yet */ + ablas_invalid_matA, /**< Matrix A is not a valid memory object */ + ablas_invalid_matB, /**< Matrix B is not a valid memory object */ + ablas_invalid_matC, /**< Matrix C is not a valid memory object */ + ablas_invalid_vecX, /**< Vector X is not a valid memory object */ + ablas_invalid_becY, /**< Vector Y is not a valid memory object */ + ablas_invalid_dim, /**< An input dimension (M,N,K) is invalid */ + ablas_invalid_leadDimA, /**< Leading dimension A must not be less than the size of the first dimension */ + ablas_invalid_leadDimB, /**< Leading dimension B must not be less than the size of the second dimension */ + ablas_invalid_leadDimC, /**< Leading dimension C must not be less than the size of the third dimension */ + ablas_invalid_incx, /**< The increment for a vector X must not be 0 */ + ablas_invalid_incy, /**< The increment for a vector Y must not be 0 */ + } ablas_status; + + + + + /* ============================================================================================ */ + /*! \brief memory allocation on GPU devie memory */ + template + ablas_status + ablas_malloc_device(T** ptr, size_t bytes ){ + return hipMalloc(ptr, bytes); + }; + + /*! \brief memory allocation on GPU host pinned memmory */ + template + ablas_status + ablas_malloc_host(T** ptr, size_t bytes ){ + return hipMallocHost(ptr, bytes); + }; + + +#endif + diff --git a/src/include/ablas_netlib.h b/src/include/ablas_netlib.h index fe6302efd..bd0417fc5 100644 --- a/src/include/ablas_netlib.h +++ b/src/include/ablas_netlib.h @@ -1,18 +1,7 @@ /* ************************************************************************ - * Copyright 2013 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ************************************************************************/ + * ************************************************************************ */ #pragma once #ifndef _ABLAS_NETLIB_H_ diff --git a/src/include/ablas_netlib_batched.h b/src/include/ablas_netlib_batched.h index c9fb32e4f..4de212180 100644 --- a/src/include/ablas_netlib_batched.h +++ b/src/include/ablas_netlib_batched.h @@ -1,18 +1,7 @@ /* ************************************************************************ - * Copyright 2013 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ************************************************************************/ + * ************************************************************************ */ #pragma once #ifndef _ABLAS_BATCHED_H_ diff --git a/src/include/ablas_runtime.h b/src/include/ablas_runtime.h index ae3be2d0b..fc7975568 100644 --- a/src/include/ablas_runtime.h +++ b/src/include/ablas_runtime.h @@ -1,17 +1,6 @@ /* ************************************************************************ - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http:// www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. * ************************************************************************ */ #pragma once @@ -19,8 +8,6 @@ #define _ABLAS_RUNTIME_H_ #include "ablas_types.h" -#include -#include /*!\file * \brief ABLAS Runtime APIs: error handling, memory allocation, device management, stream management. @@ -34,6 +21,16 @@ * =========================================================================== */ + #define CHECK_ABLAS_ERROR(error) \ + if (error != ablas_success) { \ + fprintf(stderr, "error: '%s'(%d) at %s:%d\n", ablas_get_error_string(error), error,__FILE__, __LINE__); \ + exit(EXIT_FAILURE);\ + } + +#ifdef __cplusplus +extern "C" { +#endif + /* ============================================================================================ */ /* Error Handling */ @@ -42,220 +39,119 @@ //ablas_status is a superset of hip error, non-hip-runtime error won't be detected and reported by them /*! \brief Return last error returned by any HIP runtime API call and resets the stored error code to ablas_success. */ - ablas_status ablas_get_last_error( void ){ - return hipGetLastError(); - } + ablas_status ablas_get_last_error( void ); /*! \brief Return last error returned by any HIP runtime API call. */ - ablas_status ablas_peek_at_last_error ( void ){ - return hipPeekAtLastError(); - } + ablas_status ablas_peek_at_last_error ( void ); /*! \brief Return name of the specified error code in text form. */ - const char* ablas_get_error_name(ablas_status ablas_error) - { - return hipGetErrorName (ablas_error); - } + const char* ablas_get_error_name(ablas_status ablas_error); /*! \brief Return handy text string message to explain the error which occurred. On HCC, it is the same as ablas_get_error_name() */ - const char* ablas_get_error_string(ablas_status ablas_error) - { - return hipGetErrorString (ablas_error); - } + const char* ablas_get_error_string(ablas_status ablas_error); - #define CHECK_ABLAS_ERROR(error) \ - if (error != ablas_success) { \ - fprintf(stderr, "error: '%s'(%d) at %s:%d\n", ablas_get_error_string(error), error,__FILE__, __LINE__); \ - exit(EXIT_FAILURE);\ - } /* ============================================================================================ */ - /*! \brief memory allocation on GPU devie memory */ - template - ablas_status - ablas_malloc_device(T** ptr, size_t bytes ){ - return hipMalloc(ptr, bytes); - }; - - /*! \brief memory allocation on GPU host pinned memmory */ - template - ablas_status - ablas_malloc_host(T** ptr, size_t bytes ){ - return hipMallocHost(ptr, bytes); - }; + /*! \brief memory allocation on GPU devie memory in ablas_hip.h */ /*! \brief memory free on GPU devie memory */ ablas_status - ablas_free_device(void *ptr ){ - return hipFree(ptr); - }; + ablas_free_device(void *ptr ); /*! \brief memory free on GPU host pinned memmory */ ablas_status - ablas_free_host( void *ptr ){ - return hipFreeHost(ptr); - }; + ablas_free_host( void *ptr ); /*! \brief host-synchronous, supports memory from host to device, device to host, device to device and host to host */ ablas_status ablas_memcpy_host_to_host(void * dst, const void * src, - size_t sizeBytes){ - - hipMemcpy(dst, src, sizeBytes, hipMemcpyHostToHost); - } + size_t sizeBytes); ablas_status ablas_memcpy_host_to_device(void * dst, const void * src, - size_t sizeBytes){ - - hipMemcpy(dst, src, sizeBytes, hipMemcpyHostToDevice); - } - + size_t sizeBytes); ablas_status ablas_memcpy_device_to_host(void * dst, const void * src, - size_t sizeBytes){ - - hipMemcpy(dst, src, sizeBytes, hipMemcpyDeviceToHost); - } + size_t sizeBytes); ablas_status ablas_memcpy_device_to_device(void * dst, const void * src, - size_t sizeBytes){ - - hipMemcpy(dst, src, sizeBytes, hipMemcpyDeviceToDevice); - } - + size_t sizeBytes); /*! \brief src to dst asynchronously, supports memory from host to device, device to host, device to device and host to host */ ablas_status ablas_memcpy_async_host_to_host(void * dst, const void * src, size_t sizeBytes, - ablas_queue stream=0){ - - hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyHostToHost, stream); - } + ablas_queue stream); ablas_status ablas_memcpy_async_host_to_device(void * dst, const void * src, size_t sizeBytes, - ablas_queue stream=0){ - - hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyHostToDevice, stream); - } + ablas_queue stream); ablas_status ablas_memcpy_async_device_to_host(void * dst, const void * src, size_t sizeBytes, - ablas_queue stream=0){ - - hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyDeviceToHost, stream); - } + ablas_queue stream); ablas_status ablas_memcpy_async_device_to_device(void * dst, const void * src, size_t sizeBytes, - ablas_queue stream=0){ - - hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyDeviceToDevice, stream); - } + ablas_queue stream); /* ============================================================================================ */ /* device management */ /*! \brief Blocks until the default device has completed all preceding requested tasks. */ - ablas_status ablas_device_synchronize(void){ - return hipDeviceSynchronize(); - } + ablas_status ablas_device_synchronize(void); /*! \brief Destroy all resources and reset all state on the default device in the current process. */ - ablas_status ablas_device_reset(void){ - return hipDeviceReset(); - } + ablas_status ablas_device_reset(void); /*! \brief Set default device to be used for subsequent hip API calls from this thread. */ - ablas_status ablas_set_device(int device){ - return hipSetDevice (device); - } + ablas_status ablas_set_device(ablas_int device); /*! \brief Return the default device id for the calling host thread. */ - ablas_status ablas_get_device(int *device){ - return hipGetDevice (device); - } + ablas_status ablas_get_device(ablas_int *device); /*! \brief Return number of compute-capable devices. */ - ablas_status ablas_get_device_count(int *count){ - return hipGetDeviceCount (count); - } - - /*! \brief Returns device properties. */ - ablas_status ablas_device_get_properties(hipDeviceProp_t *prop, int device){ - return hipDeviceGetProperties (prop, device); - } - - /*! \brief Set L1/Shared cache partition. */ - ablas_status ablas_device_set_cache_config(hipFuncCache cacheConfig){ - return hipDeviceSetCacheConfig(cacheConfig); - } + ablas_status ablas_get_device_count(ablas_int *count); - /*! \brief Set Cache configuration for a specific function. */ - ablas_status ablas_device_get_cache_config(hipFuncCache *cacheConfig){ - return hipDeviceGetCacheConfig (cacheConfig); - } - - /*! \brief Set Cache configuration for a specific function. */ - ablas_status ablas_func_set_cache_config(hipFuncCache config){ - return hipFuncSetCacheConfig (config); - } - - /*! \brief Get Shared memory bank configuration. */ - ablas_status ablas_device_get_sharedMem_config (hipSharedMemConfig *pConfig) - return hipDeviceGetSharedMemConfig(pConfig); - } - - /*! \brief Set Shared memory bank configuration. */ - ablas_status ablas_device_set_sharedMem_config(hipSharedMemConfig config){ - return hipDeviceSetSharedMemConfig (config) - } + /* ============================================================================================ */ + /* query device :*/ + void ablas_query_device(); /* ============================================================================================ */ /* stream management */ /*! \brief Create an asynchronous stream. */ - ablas_status ablas_stream_create_withflags(ablas_queue *stream, unsigned int flags){ - return hipStreamCreateWithFlags(stream, flags); - } - + ablas_status ablas_stream_create_withflags(ablas_queue *stream, unsigned ablas_int flags); /*! \brief Make the specified compute stream wait for an event. */ - ablas_status ablas_stream_wait_event(ablas_queue stream, ablas_event event, unsigned int flags){ - return hipStreamWaitEvent(stream, event, flags); - } + ablas_status ablas_stream_wait_event(ablas_queue stream, ablas_event event, unsigned ablas_int flags); /*! \brief Wait for all commands in stream to complete. */ - ablas_status ablas_stream_synchronize(ablas_queue stream){ - return hipStreamSynchronize (stream); - } + ablas_status ablas_stream_synchronize(ablas_queue stream); /*! \brief Destroys the specified stream. */ - ablas_status ablas_stream_destroy(ablas_queue stream){ - return hipStreamDestroy(stream); - } + ablas_status ablas_stream_destroy(ablas_queue stream); /*! \brief Return flags associated with this stream. */ - ablas_status ablas_stream_get_flags(ablas_queue stream, unsigned int *flags){ - return hipStreamGetFlags(stream, flags); - } + ablas_status ablas_stream_get_flags(ablas_queue stream, unsigned ablas_int *flags); +#ifdef __cplusplus +} +#endif #endif diff --git a/src/include/ablas_types.h b/src/include/ablas_types.h index f7394f0e6..bf9d3cb85 100644 --- a/src/include/ablas_types.h +++ b/src/include/ablas_types.h @@ -1,17 +1,6 @@ /* ************************************************************************ - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. * ************************************************************************ */ /*!\file @@ -24,26 +13,13 @@ #define _ABLAS_TYPES_H_ #include -#include +#include /*! \file * \brief ablas_types.h defines data types used by ablas */ - /* - * =========================================================================== - * READEME: ABLAS Wrapper of HIP data types and APIs - * HIP is still under development. Developers of aBLAS are encouraged to use ablas APIs - * in their code, in case HIP APIs would be changed in the future. - * =========================================================================== - */ - - -typedef hipStream_t ablas_queue; -typedef hipEvent_t ablas_event; -typedef ablas_queue ablas_handle; - #ifdef __cplusplus extern "C" { @@ -99,46 +75,6 @@ extern "C" { } ablas_side; - /* ============================================================================================ */ - /** - * @brief ablas error codes definition, incorporating HIP error - * definitions. - * - * This enumeration is a subset of the HIP error codes extended with some - * additional extra codes. For example, hipErrorMemoryAllocation, which is - * defined in hip_runtime_api.h is aliased as ablas_error_memory_allocation. - */ - typedef enum ablas_status_ { - - ablas_success = hipSuccess = 0, ///< Successful completion. - ablas_error_memory_allocation = hipErrorMemoryAllocation, ///< Memory allocation error. - ablas_error_memory_free = hipErrorMemoryFree, ///< Memory free error. - ablas_error_unknown_symbol = hipErrorUnknownSymbol, ///< Unknown symbol - ablas_error_outof_resources = hipErrorOutOfResources ///< Out of resources error - ablas_error_invalid_value = hipErrorInvalidValue ///< One or more of the paramters passed to the API call is NULL or not in an acceptable range. - ablas_error_invalid_resource_handle = hipErrorInvalidResourceHandle ///< Resource handle (hipEvent_t or hipStream_t) invalid. - ablas_error_invalid_device = hipErrorInvalidDevice ///< DeviceID must be in range 0...#compute-devices. - ablas_error_no_deive = hipErrorNoDevice ///< Call to cudaGetDeviceCount returned 0 devices - ablas_error_not_ready = hipErrorNotReady ///< indicates that asynchronous operations enqueued earlier are not ready. - /// This is not actually an error, but is used to distinguish from hipSuccess(which indicates completion). - /// APIs that return this error include hipEventQuery and hipStreamQuery. - /* Extended error codes */ - ablas_not_implemented = -1024, /**< Functionality is not implemented */ - ablas_not_initialized, /**< ablas library is not initialized yet */ - ablas_invalid_matA, /**< Matrix A is not a valid memory object */ - ablas_invalid_matB, /**< Matrix B is not a valid memory object */ - ablas_invalid_matC, /**< Matrix C is not a valid memory object */ - ablas_invalid_vecX, /**< Vector X is not a valid memory object */ - ablas_invalid_becY, /**< Vector Y is not a valid memory object */ - ablas_invalid_dim, /**< An input dimension (M,N,K) is invalid */ - ablas_invalid_leadDimA, /**< Leading dimension A must not be less than the size of the first dimension */ - ablas_invalid_leadDimB, /**< Leading dimension B must not be less than the size of the second dimension */ - ablas_invalid_leadDimC, /**< Leading dimension C must not be less than the size of the third dimension */ - ablas_invalid_incx, /**< The increment for a vector X must not be 0 */ - ablas_invalid_incy, /**< The increment for a vector Y must not be 0 */ - } ablas_status; - - /* ============================================================================================ */ @@ -154,65 +90,13 @@ extern "C" { */ typedef float2 ablas_float_complex typedef double2 ablas_double_complex - - #define ABLAS_ONE 1 - #define ABLAS_NEG_ONE -1 - #define ABLAS_ZERO 0 - - #define ABLAS_Z_MAKE(r,i) - #define ABLAS_Z_REAL(a) (a).x - #define ABLAS_Z_IMAG(a) (a).y - #define ABLAS_Z_ADD(a, b) - #define ABLAS_Z_SUB(a, b) - #define ABLAS_Z_MUL(a, b) - #define ABLAS_Z_DIV(a, b) - #define ABLAS_Z_ABS(a) - #define ABLAS_Z_ABS1(a) (fabs((a).x) + fabs((a).y)) - #define ABLAS_Z_CONJ(a) - - #define ABLAS_C_MAKE(r,i) - #define ABLAS_C_REAL(a) (a).x - #define ABLAS_C_IMAG(a) (a).y - #define ABLAS_C_ADD(a, b) - #define ABLAS_C_SUB(a, b) - #define ABLAS_C_MUL(a, b) - #define ABLAS_C_DIV(a, b) - #define ABLAS_C_ABS(a) - #define ABLAS_C_ABS1(a) (fabsf((a).x) + fabsf((a).y)) - #define ABLAS_C_CONJ(a) + // A Lot TODO about complex #ifdef __cplusplus } #endif -/* ============================================================================================ */ - -/*! \brief Struct used to parse command line arguments in testing. */ - -struct arguments { - ablas_int M; - ablas_int N; - ablas_int K; - - ablas_int start; - ablas_int end; - ablas_int step; - - double alpha; - double beta; - - char transA_option; - char transB_option; - char side_option; - char uplo_option; - char diag_option; - - ablas_int apiCallCount; - ablas_int order_option; - ablas_int validate; -} ; - /* ============================================================================================ */ diff --git a/src/library/ablas_runtime.cpp b/src/library/ablas_runtime.cpp new file mode 100644 index 000000000..ea5ad37d4 --- /dev/null +++ b/src/library/ablas_runtime.cpp @@ -0,0 +1,233 @@ +/* ************************************************************************ + * Copyright 2016 Advanced Micro Devices, Inc. + * + * ************************************************************************ */ + +#include "stdio.h" +#include "ablas_types.h" +#include + + + /* + * =========================================================================== + * READEME: ABLAS Wrapper of HIP data types and APIs + * HIP is still under development. Developers of aBLAS are encouraged to use ablas APIs + * in their code, in case HIP APIs would be changed in the future. + * =========================================================================== + */ + + /* ============================================================================================ */ + + /* Error Handling */ + + //warning: the four error handling API only get and return recent HIP API error + //ablas_status is a superset of hip error, non-hip-runtime error won't be detected and reported by them + + /*! \brief Return last error returned by any HIP runtime API call and resets the stored error code to ablas_success. */ + extern "C" ablas_status ablas_get_last_error( void ){ + return hipGetLastError(); + } + + /*! \brief Return last error returned by any HIP runtime API call. */ + extern "C" ablas_status ablas_peek_at_last_error ( void ){ + return hipPeekAtLastError(); + } + + /*! \brief Return name of the specified error code in text form. */ + extern "C" const char* ablas_get_error_name(ablas_status ablas_error) + { + return hipGetErrorName (ablas_error); + } + + /*! \brief Return handy text string message to explain the error which occurred. On HCC, it is the same as ablas_get_error_name() */ + extern "C" const char* ablas_get_error_string(ablas_status ablas_error) + { + return hipGetErrorString (ablas_error); + } + + /* ============================================================================================ */ + /*! \brief memory allocation on GPU devie memory is on header file */ + + /*! \brief memory free on GPU devie memory */ + extern "C" ablas_status + ablas_free_device(void *ptr ){ + return hipFree(ptr); + }; + + /*! \brief memory free on GPU host pinned memmory */ + extern "C" ablas_status + ablas_free_host( void *ptr ){ + return hipFreeHost(ptr); + }; + + /*! \brief host-synchronous, supports memory from host to device, device to host, device to device and host to host */ + extern "C" ablas_status + ablas_memcpy_host_to_host(void * dst, + const void * src, + size_t sizeBytes){ + + hipMemcpy(dst, src, sizeBytes, hipMemcpyHostToHost); + } + + extern "C" ablas_status + ablas_memcpy_host_to_device(void * dst, + const void * src, + size_t sizeBytes){ + + hipMemcpy(dst, src, sizeBytes, hipMemcpyHostToDevice); + } + + extern "C" ablas_status + ablas_memcpy_device_to_host(void * dst, + const void * src, + size_t sizeBytes){ + + hipMemcpy(dst, src, sizeBytes, hipMemcpyDeviceToHost); + } + + extern "C" ablas_status + ablas_memcpy_device_to_device(void * dst, + const void * src, + size_t sizeBytes){ + + hipMemcpy(dst, src, sizeBytes, hipMemcpyDeviceToDevice); + } + + + /*! \brief src to dst asynchronously, supports memory from host to device, device to host, device to device and host to host */ + extern "C" ablas_status + ablas_memcpy_async_host_to_host(void * dst, + const void * src, + size_t sizeBytes, + ablas_queue stream){ + + hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyHostToHost, stream); + } + + extern "C" ablas_status + ablas_memcpy_async_host_to_device(void * dst, + const void * src, + size_t sizeBytes, + ablas_queue stream){ + + hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyHostToDevice, stream); + } + + extern "C" ablas_status + ablas_memcpy_async_device_to_host(void * dst, + const void * src, + size_t sizeBytes, + ablas_queue stream){ + + hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyDeviceToHost, stream); + } + + extern "C" ablas_status + ablas_memcpy_async_device_to_device(void * dst, + const void * src, + size_t sizeBytes, + ablas_queue stream){ + + hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyDeviceToDevice, stream); + } + + /* ============================================================================================ */ + + /* device management */ + + /*! \brief Blocks until the default device has completed all preceding requested tasks. */ + extern "C" ablas_status ablas_device_synchronize(void){ + return hipDeviceSynchronize(); + } + + /*! \brief Destroy all resources and reset all state on the default device in the current process. */ + extern "C" ablas_status ablas_device_reset(void){ + return hipDeviceReset(); + } + + /*! \brief Set default device to be used for subsequent hip API calls from this thread. */ + extern "C" ablas_status ablas_set_device(ablas_int device){ + return hipSetDevice (device); + } + + /*! \brief Return the default device id for the calling host thread. */ + extern "C" ablas_status ablas_get_device(ablas_int *device){ + return hipGetDevice (device); + } + + /*! \brief Return number of compute-capable devices. */ + extern "C" ablas_status ablas_get_device_count(ablas_int *count){ + return hipGetDeviceCount (count); + } + + /*! \brief Returns device properties. */ + extern "C" ablas_status ablas_device_get_properties(hipDeviceProp_t *prop, ablas_int device){ + return hipDeviceGetProperties (prop, device); + } + + /*! \brief Set L1/Shared cache partition. */ + extern "C" ablas_status ablas_device_set_cache_config(hipFuncCache cacheConfig){ + return hipDeviceSetCacheConfig(cacheConfig); + } + + /*! \brief Set Cache configuration for a specific function. */ + extern "C" ablas_status ablas_device_get_cache_config(hipFuncCache *cacheConfig){ + return hipDeviceGetCacheConfig (cacheConfig); + } + + /*! \brief Set Cache configuration for a specific function. */ + extern "C" ablas_status ablas_func_set_cache_config(hipFuncCache config){ + return hipFuncSetCacheConfig (config); + } + + /*! \brief Get Shared memory bank configuration. */ + extern "C" ablas_status ablas_device_get_sharedMem_config (hipSharedMemConfig *pConfig){ + return hipDeviceGetSharedMemConfig(pConfig); + } + + /*! \brief Set Shared memory bank configuration. */ + extern "C" ablas_status ablas_device_set_sharedMem_config(hipSharedMemConfig config){ + return hipDeviceSetSharedMemConfig (config) + } + + /* ============================================================================================ */ + /* query device :*/ + extern "C" void ablas_query_device() + { + int num_device, device_id=0; + ablas_get_device_count(&num_device); + ablas_set_device(device_id); + + printf("There are %d GPU devices; running on device ID %d \n", num_device, device_id); + } + + /* ============================================================================================ */ + + /* stream management */ + + /*! \brief Create an asynchronous stream. */ + extern "C" ablas_status ablas_stream_create_withflags(ablas_queue *stream, unsigned ablas_int flags){ + return hipStreamCreateWithFlags(stream, flags); + } + + /*! \brief Make the specified compute stream wait for an event. */ + extern "C" ablas_status ablas_stream_wait_event(ablas_queue stream, ablas_event event, unsigned ablas_int flags){ + return hipStreamWaitEvent(stream, event, flags); + } + + /*! \brief Wait for all commands in stream to complete. */ + extern "C" ablas_status ablas_stream_synchronize(ablas_queue stream){ + return hipStreamSynchronize (stream); + } + + /*! \brief Destroys the specified stream. */ + extern "C" ablas_status ablas_stream_destroy(ablas_queue stream){ + return hipStreamDestroy(stream); + } + + /*! \brief Return flags associated with this stream. */ + extern "C" ablas_status ablas_stream_get_flags(ablas_queue stream, unsigned ablas_int *flags){ + return hipStreamGetFlags(stream, flags); + } + + diff --git a/src/include/ablas_flops.h b/src/testing/flops.h similarity index 100% rename from src/include/ablas_flops.h rename to src/testing/flops.h diff --git a/src/include/ablas_utility.h b/src/testing/testing_utility.cpp similarity index 62% rename from src/include/ablas_utility.h rename to src/testing/testing_utility.cpp index 891fa11bf..cbb0a1d2d 100644 --- a/src/include/ablas_utility.h +++ b/src/testing/testing_utility.cpp @@ -1,60 +1,17 @@ /* ************************************************************************ - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2016 Advanced Micro Devices, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http:// www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. * ************************************************************************ */ -#pragma once -#ifndef _ABLAS_UTILITY_H_ -#define _ABLAS_UTILITY_H_ #include "ablas_types.h" -#include "ablas_runtime.h" #include -/*!\file - * \brief provide random generator, device query, timing, etc, utilities. - */ - - /* ============================================================================================ */ - /* generate random number :*/ - - /*! \brief generate a random number between [0, 0.999...] . */ - template - T random_generator(){ - return rand()/( (T)RAND_MAX + 1) - } #ifdef __cplusplus extern "C" { #endif - /* ============================================================================================ */ - /* query device :*/ - - void ablas_get_device_property() - { - - int num_device, device_id=0; - - ablas_get_device_count(&num_device); - - ablas_set_device(device_id); - - printf("There are %d GPU devices; running on device ID %d \n", num_device, device_id); - - } - /* ============================================================================================ */ /* timing:*/ @@ -76,26 +33,6 @@ extern "C" { return (tv.tv_sec * 1000) + tv.tv_usec /1000; }; - /* ============================================================================================ */ - /* integer functions */ - - /*! \brief For integers x >= 0, y > 0, returns ceil( x/y ). - * For x == 0, this is 0. - */ - __host__ __device__ - static inline ablas_int ablas_ceildiv( ablas_int x, ablas_int y ) - { - return (x + y - 1)/y; - } - - /*! \brief For integers x >= 0, y > 0, returns x rounded up to multiple of y. - * For x == 0, this is 0. y is not necessarily a power of 2. - */ - __host__ __device__ - static inline ablas_int ablas_roundup( ablas_int x, ablas_int y ) - { - return ablas_ceildiv( x, y ) * y; - } /* ============================================================================================ */ /* Convert ablas constants to lapack char. */ @@ -198,5 +135,4 @@ extern "C" { } #endif -#endif diff --git a/src/testing/testing_utility.h b/src/testing/testing_utility.h new file mode 100644 index 000000000..d6805c44f --- /dev/null +++ b/src/testing/testing_utility.h @@ -0,0 +1,105 @@ +/* ************************************************************************ + * Copyright 2016 Advanced Micro Devices, Inc. + * + * ************************************************************************ */ + +#pragma once +#ifndef _TESTING_UTILITY_H_ +#define _TESTING_UTILITY_H_ + +#include "ablas_types.h" +#include + +/*!\file + * \brief provide random generator, device query, timing, etc, utilities. + */ + + /* ============================================================================================ */ + /* generate random number :*/ + + /*! \brief generate a random number between [0, 0.999...] . */ + template + T random_generator(){ + return rand()/( (T)RAND_MAX + 1) + } + + +#ifdef __cplusplus +extern "C" { +#endif + + /* ============================================================================================ */ + /* timing:*/ + + /*! \brief CPU Timer(in millisecond): synchronize with the default device and return wall time */ + double ablas_wtime( void ); + + + /*! \brief CPU Timer(in millisecond): synchronize with given queue/stream and return wall time */ + double ablas_sync_wtime( ablas_queue queue ); + + /* ============================================================================================ */ + /* Convert ablas constants to lapack char. */ + + char + ablas2lapack_transpose(ablas_transpose value); + + char + ablas2lapack_uplo(ablas_uplo value); + + char + ablas2lapack_diag(ablas_diag value); + + char + ablas2lapack_side(ablas_side value); + + /* ============================================================================================ */ + /* Convert lapack char constants to ablas type. */ + + ablas_transpose + lapack2ablas_transpose(char value); + + ablas_uplo + lapack2ablas_uplo(char value); + + ablas_diag + lapack2ablas_diag(char value); + + ablas_side + lapack2ablas_side(char value); + +#ifdef __cplusplus +} +#endif + + +/* ============================================================================================ */ + +/*! \brief Struct used to parse command line arguments in testing. */ + +struct arguments { + ablas_int M; + ablas_int N; + ablas_int K; + + ablas_int start; + ablas_int end; + ablas_int step; + + double alpha; + double beta; + + char transA_option; + char transB_option; + char side_option; + char uplo_option; + char diag_option; + + ablas_int apiCallCount; + ablas_int order_option; + ablas_int validate; +} ; + + +#endif +