@@ -1909,23 +1909,90 @@ pi_result cuda_piProgramGetInfo(pi_program program, pi_program_info param_name,
19091909 return {};
19101910}
19111911
1912- pi_result cuda_piProgramLink ( // TODO: change interface to return error code
1912+ pi_result cuda_piProgramLink (
19131913 pi_context context, pi_uint32 num_devices, const pi_device *device_list,
19141914 const char *options, pi_uint32 num_input_programs,
19151915 const pi_program *input_programs,
19161916 void (*pfn_notify)(pi_program program, void *user_data), void *user_data,
19171917 pi_program *ret_program) {
1918- cl::sycl::detail::pi::die (" cuda_piProgramLink not implemented" );
1919- return {};
1918+
1919+ assert (ret_program != nullptr );
1920+ assert (num_devices == 1 || num_devices == 0 );
1921+ assert (device_list != nullptr || num_devices == 0 );
1922+ assert (pfn_notify == nullptr );
1923+ assert (user_data == nullptr );
1924+ pi_result retError = PI_SUCCESS;
1925+
1926+ try {
1927+ ScopedContext active (context);
1928+
1929+ CUlinkState state;
1930+ std::unique_ptr<_pi_program> retProgram{new _pi_program{context}};
1931+
1932+ // TODO: Linker options
1933+ retError = PI_CHECK_ERROR (cuLinkCreate (0 , nullptr , nullptr , &state));
1934+ try {
1935+ for (size_t i; i < num_input_programs; ++i) {
1936+ pi_program program = input_programs[i];
1937+ std::vector<char > source (program->source_ ,
1938+ program->source_ + program->sourceLength_ );
1939+ retError = PI_CHECK_ERROR (cuLinkAddData (
1940+ state, CU_JIT_INPUT_PTX, source.data (), program->sourceLength_ ,
1941+ nullptr , 0 , nullptr , nullptr ));
1942+ }
1943+ void *cubin = nullptr ;
1944+ size_t cubinSize = 0 ;
1945+ retError = PI_CHECK_ERROR (cuLinkComplete (state, &cubin, &cubinSize));
1946+
1947+ retError = retProgram->create_from_source (
1948+ static_cast <const char *>(cubin), cubinSize);
1949+
1950+ if (retError != PI_SUCCESS) {
1951+ return retError;
1952+ }
1953+
1954+ retError = retProgram->build_program (options);
1955+
1956+ if (retError != PI_SUCCESS) {
1957+ return retError;
1958+ }
1959+ } catch (...) {
1960+ // Upon error attempt cleanup
1961+ PI_CHECK_ERROR (cuLinkDestroy (state));
1962+ throw ;
1963+ }
1964+
1965+ retError = PI_CHECK_ERROR (cuLinkDestroy (state));
1966+ *ret_program = retProgram.release ();
1967+
1968+ } catch (pi_result err) {
1969+ retError = err;
1970+ }
1971+ return retError;
19201972}
19211973
19221974pi_result cuda_piProgramCompile (
19231975 pi_program program, pi_uint32 num_devices, const pi_device *device_list,
19241976 const char *options, pi_uint32 num_input_headers,
19251977 const pi_program *input_headers, const char **header_include_names,
19261978 void (*pfn_notify)(pi_program program, void *user_data), void *user_data) {
1927- cl::sycl::detail::pi::die (" cuda_piProgramCompile not implemented" );
1928- return {};
1979+ assert (program != nullptr );
1980+ assert (num_devices == 1 || num_devices == 0 );
1981+ assert (device_list != nullptr || num_devices == 0 );
1982+ assert (pfn_notify == nullptr );
1983+ assert (user_data == nullptr );
1984+ assert (num_input_headers == 0 );
1985+ pi_result retError = PI_SUCCESS;
1986+
1987+ try {
1988+ ScopedContext active (program->get_context ());
1989+
1990+ program->build_program (options);
1991+
1992+ } catch (pi_result err) {
1993+ retError = err;
1994+ }
1995+ return retError;
19291996}
19301997
19311998pi_result cuda_piProgramGetBuildInfo (pi_program program, pi_device device,
0 commit comments