@@ -1935,23 +1935,89 @@ pi_result cuda_piProgramGetInfo(pi_program program, pi_program_info param_name,
1935
1935
return {};
1936
1936
}
1937
1937
1938
- pi_result cuda_piProgramLink ( // TODO: change interface to return error code
1939
- pi_context context, pi_uint32 num_devices, const pi_device *device_list,
1940
- const char *options, pi_uint32 num_input_programs,
1941
- const pi_program *input_programs,
1942
- void (*pfn_notify)(pi_program program, void *user_data), void *user_data,
1943
- pi_program *ret_program) {
1944
- cl::sycl::detail::pi::die (" cuda_piProgramLink not implemented" );
1945
- return {};
1938
+ pi_result cuda_piProgramLink (pi_context context, pi_uint32 num_devices,
1939
+ const pi_device *device_list, const char *options,
1940
+ pi_uint32 num_input_programs,
1941
+ const pi_program *input_programs,
1942
+ void (*pfn_notify)(pi_program program,
1943
+ void *user_data),
1944
+ void *user_data, pi_program *ret_program) {
1945
+
1946
+ assert (ret_program != nullptr );
1947
+ assert (num_devices == 1 || num_devices == 0 );
1948
+ assert (device_list != nullptr || num_devices == 0 );
1949
+ assert (pfn_notify == nullptr );
1950
+ assert (user_data == nullptr );
1951
+ pi_result retError = PI_SUCCESS;
1952
+
1953
+ try {
1954
+ ScopedContext active (context);
1955
+
1956
+ CUlinkState state;
1957
+ std::unique_ptr<_pi_program> retProgram{new _pi_program{context}};
1958
+
1959
+ // TODO: Linker options
1960
+ retError = PI_CHECK_ERROR (cuLinkCreate (0 , nullptr , nullptr , &state));
1961
+ try {
1962
+ for (size_t i = 0 ; i < num_input_programs; ++i) {
1963
+ pi_program program = input_programs[i];
1964
+ retError = PI_CHECK_ERROR (cuLinkAddData (
1965
+ state, CU_JIT_INPUT_PTX, const_cast <char *>(program->source_ ),
1966
+ program->sourceLength_ , nullptr , 0 , nullptr , nullptr ));
1967
+ }
1968
+ void *cubin = nullptr ;
1969
+ size_t cubinSize = 0 ;
1970
+ retError = PI_CHECK_ERROR (cuLinkComplete (state, &cubin, &cubinSize));
1971
+
1972
+ retError = retProgram->create_from_source (
1973
+ static_cast <const char *>(cubin), cubinSize);
1974
+
1975
+ if (retError != PI_SUCCESS) {
1976
+ return retError;
1977
+ }
1978
+
1979
+ retError = retProgram->build_program (options);
1980
+
1981
+ if (retError != PI_SUCCESS) {
1982
+ return retError;
1983
+ }
1984
+ } catch (...) {
1985
+ // Upon error attempt cleanup
1986
+ PI_CHECK_ERROR (cuLinkDestroy (state));
1987
+ throw ;
1988
+ }
1989
+
1990
+ retError = PI_CHECK_ERROR (cuLinkDestroy (state));
1991
+ *ret_program = retProgram.release ();
1992
+
1993
+ } catch (pi_result err) {
1994
+ retError = err;
1995
+ }
1996
+ return retError;
1946
1997
}
1947
1998
1948
1999
pi_result cuda_piProgramCompile (
1949
2000
pi_program program, pi_uint32 num_devices, const pi_device *device_list,
1950
2001
const char *options, pi_uint32 num_input_headers,
1951
2002
const pi_program *input_headers, const char **header_include_names,
1952
2003
void (*pfn_notify)(pi_program program, void *user_data), void *user_data) {
1953
- cl::sycl::detail::pi::die (" cuda_piProgramCompile not implemented" );
1954
- return {};
2004
+ assert (program != nullptr );
2005
+ assert (num_devices == 1 || num_devices == 0 );
2006
+ assert (device_list != nullptr || num_devices == 0 );
2007
+ assert (pfn_notify == nullptr );
2008
+ assert (user_data == nullptr );
2009
+ assert (num_input_headers == 0 );
2010
+ pi_result retError = PI_SUCCESS;
2011
+
2012
+ try {
2013
+ ScopedContext active (program->get_context ());
2014
+
2015
+ program->build_program (options);
2016
+
2017
+ } catch (pi_result err) {
2018
+ retError = err;
2019
+ }
2020
+ return retError;
1955
2021
}
1956
2022
1957
2023
pi_result cuda_piProgramGetBuildInfo (pi_program program, pi_device device,
0 commit comments