DrTimothyAldenDavis / SuiteSparse

The official SuiteSparse library: a suite of sparse matrix algorithms authored or co-authored by Tim Davis, Texas A&M University.
https://people.engr.tamu.edu/davis/suitesparse.html
Other
1.11k stars 256 forks source link

Building SuiteSparse for use on iOS platform, fails on coding signing step of JITpackage. #835

Open sbelbin opened 3 weeks ago

sbelbin commented 3 weeks ago

Describe the bug Building SuiteSparse to target the iOS platform such as Apple's iPad the Cmake build fails at code signing phase for the JITpackage.

To Reproduce

  1. Clone the ios-cmake toolchain from here https://github.com/leetal/ios-cmake in a folder above SuiteSparse folder.
  2. Download and build GMP, MPFR and OpenMP and build it for the iOS platform.
  3. Clone the SuiteSparse from GitHub.
  4. cd SuiteSparse
  5. cmake -B build -G Xcode --toolchain ../ios-cmake/ios.toolchain.cmake -DPLATFORM=OS64 -DCMAKE_INSTALL_PREFIX=../install/OS64/suitesparse .
  6. cmake --build ./build

Expected behavior Expectation that the JITpackage to build and for code signing to occur.

Screenshots /Users/yul/tmp/SuiteSparse/build/GraphBLAS/JITpackage/native/jitpackage.xcodeproj: error: Signing for "grb_jitpackage" requires a development team. Select a development team in the Signing & Capabilities editor. (in target 'grb_jitpackage' from project 'jitpackage')

Desktop (please complete the following information):

Additional context Our development environment is a MacBook Pro. Our C/C++ library is build using Visual Studio Code along with CMake, whereas the iPad app is written in Swift in Xcode with a bridging header to integrate our C library to the iPad app.

The SuiteSparse dependencies of GMP, MPFR and OpenMP have been built the iOS platform and the SuiteSparse code is referring to the appropriate include and lib folders.

I've tried disabling the building of shared library via the -DBUILD_SHARED_LIBS=OFF option on the CMake comand line. Hoping that since we are building to be a static library that it would forego this code signing step.

Additionally, I've tried setting these CMake definitions below hoping what was missing was a certificate to use when signing the code.

set ( CPACK_BUNDLE_APPLE_CERT_APP "Apple Development: FirstName LastName (XX9X9X9XXX)") set ( CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "XX9X9X9XXX" ) set ( CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development" ) set ( CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Manual" )

sbelbin commented 3 weeks ago

Thanks to the JITIFYER for SuiteSparse:GraphBLAS video posted last year on YouTube I saw what the JIT does.

Our particular application targets iOS platform is Apple's iPad devices (which includes the blazing fast Apple iPad Pro with a M4 chip) the compiler won't allow invoking the system in the function GB_jitifyer_command within _GraphBLAS/Source/GBjitifyer.c. Therefore, our situation doesn't need a JIT.

Thus, I provided to CMake to prepare the option of -DGRAPHBLAS_USE_JIT=OFF.

Even with that option specified, I still had to do the following to get it to build for Apple's iOS platform.

  1. Provide NJIT as a compiler directive.
  2. Modified the GB_jitifyer_command to disable the call to system, since we don't use it for our context.

These above 2 points are my hacks. However, they should be address for others whom liked to build for Apple's iOS platform.

IMHO, the solution is within GraphBLAS CMake such that:

I'd like to end with, I appreciate everyone time and effort on making SuiteSparse available.

P.S. I still have to do runtime validations on the Apple's iOS. But, that's the next step.

mmuetzel commented 3 weeks ago

Thank you for your report.

IIUC, you'd like to cross-compile GraphBLAS on macOS for iOS. I don't know much about development for iOS. But you might need to follow the notes for cross-compilation here: https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/13806726cbf470914d012d132a85aea1aff9ee77/GraphBLAS/JITpackage/README.md#cross-compilation

Which errors exactly do you see when you are trying to build with -DGRAPHBLAS_USE_JIT=OFF (before you manually defined NJIT)?

DrTimothyAldenDavis commented 3 weeks ago

I could revise the building of the JIT to handle this case, by allowing those features to be turned off. I'd like to understand the problem some more, first.

can you point me to the Apple documentation where they disable the call to system(...) on the iOS?

The JIT is very important for best performance in GraphBLAS. If the end user application tries to do anything not handled by my FactoryKernels, then a 'generic' kernel is used. A generic kernel implements all typecasting and all operators (the add and times of the semiring for example) with calls to function pointer. Each assignment is a memcpy, one per scalar. So it's very slow. It can be 10x slower than a compiled kernel (either built-in FactoryKernel or a JIT kernel).

If Apple disables the system(...) call, that's a serious limitation, but there is a powerful solution that can mitigate that issue: my PreJIT feature.

With no call to system(..), the JIT cannot be used at run time. But it still can be used at compile time, when you are building the library for iOS.

Imagine you run an application that calls GraphBLAS, with the JIT enabled (say you do it on the Mac, not iOS). When GraphBLAS encounters the need to compile a JIT kernel, it compiles it and then saves it (by default, in ~/.SuiteSparse/GrB9.3.0 for GraphBLAS 9.3.0). Say the end application encounters the need to compile a 100 JIT kernels. The source code for those is placed in ~/.SuiteSparse/GrB9.3.0/c//.c. The compiled libraries are in ~/.SuiteSparse/GrB9.3.0/lib//.dylib. That way, the next time the application runs, it can find its already-compiled kernels. So far, no PreJIT.

Now, after the application has been exercised fully (in development on the Mac), it has likely compiled all the JIT kernels it would encounter in production. Then close the application, and do

cp ~/.SuiteSparse/GrB9.3.0/c//.c ~/mydevelopmentfolder/SuiteSparse/GraphBLAS/PreJIT

and rebuild the GraphBLAS library. The cmake build system will find these new kernels and compile them directly into the libgraphblas.dylib, as PreJIT kernels. Then the end user application does not ever need to call the JIT to compile those kernels. They are baked into libgraphblas.dylib. No need to call system(...), so this would work on the iOS.

The JIT control would be GxB_JIT_RUN, which enables the running of JIT kernels (PreJIT only, in this case) that are already loaded. The PreJIT kernels can be run, and no new JIT kernels can be loaded or compiled. The system(..) won't be used. The PreJIT kernels are not loaded with dlopen/dlsym anyway. I find them and hash them at GrB_init time.

Say you missed a case when exercising the application. No worries ... I'll punt to the generic case for that when the JIT control is GxB_JIT_RUN, because that tells me I can only run the JIT kernels already loaded. You can thus selectively copy just the JIT kernels that are critical for performance from ~/.SuiteSparse/GrB9.3.0/c//.c into the GraphBLAS/PreJIT. That can be useful because some JIT kernels are not so critical. For example, I compile different JIT kernels for different input matrix formats. If an algorithm expects a matrix to be large and sparse, that's one JIT kernel. But if the matrix becomes small enough, I might switch to a different format, thus triggering a different JIT kernel. In that case, however, if the matrix is small, the run time of the generic kernel will be fast enough.

I wrote the PreJIT just for this case, when the end user application is not allowed to compile its own JIT kernels for whatever reason: say an embedded system with no compiler, or a setup where the end user is not expected to require a compiler, or perhaps for security reasons since 'system (" gcc ... whatever")' could be a security risk that is not needed. The iPad fits all those constraints: it seems to have no built-in compiler anyway, on the iPad itself, and they also disable the call to system(...).

So you could still use the JIT in the GxB_JIT_RUN state.

Setting GRAPHBLAS_USE_JIT to ON disables the JIT, and the JIT control is GxB_JIT_RUN. PreJIT kernels can then be used but no new JIT kernels can be compiled, and no JIT kernels in ~/.SuiteSparse/GrB9.3.0/lib//.dylib can even be loaded.

See the discussion of the JIT in the user guide for details.

The NJIT flag predates the cmake GRAPHBLAS_USE_JIT option. If GRAPHBLAS_USE_JIT is enabled by cmake, it sets NJIT itself. So you should not need to set NJIT yourself. Also, with this case, the GB_jitifyer_command function is never called. So changing it to the following would be safe, and it might avoid a compiler error if the system() function is not even available as a non-working stub:

static void GB_jitifyer_command (char *command)
{ 
    #ifndef NJIT
    int result = system (command) ;
    #endif
}

That change would not disable any PreJIT kernels and would not have any impact on GraphBLAS at all.

IMHO, the solution is within GraphBLAS CMake such that:

  • When specifying the GRAPHBLAS_USE_JIT=OFF, CMake won't build any code in the JIT folder.

You mean the GraphBLAS/JITpackage folder? I think that should be possible. The cmake build system has to package the source code for my JIT kernels into the constructed GB_JITpackage.c file, but I do not need those files if GRAPHBLAS_USE_JIT is OFF. In particular, the GB_JITpackage.c file that I build looks like this already:

#ifdef NJIT
// JIT is disabled at compile time
int GB_JITpackage_nfiles = 0 ;
GB_JITpackage_index_struct GB_JITpackage_index [1] = {{0, 0, NULL, NULL}} ;
#else
... lots and lots of compress binary files here, ready to create ~/.SuiteSparse/GrB9.3.0/src at GrB_init time but these are not used if GRAPHBLAS_USE_JIT is OFF ...
#endif
  • Provide directives which are platform specific such as Apple

I think I already have some cross-compiling instructions, but I can try to clarify them.

  • s iOS to automatically GRAPHBLAS_USE_JIT=OFF .

I'm not sure how to detect that case.

  • Wrap a test C program with system, if it fails then set GRAPHBLAS_USE_JIT=OFF.

That should be possible. Does a code with a call to system(..) fail to compile entirely? That would be easier to test in cmake. If it compiles but fails to run, it would be trickier to handle since I would need to provide a dummy command to call, like "system('ls')" but that would probably fail on Windows.

DrTimothyAldenDavis commented 3 weeks ago

I'm testing this now: https://github.com/DrTimothyAldenDavis/SuiteSparse/commit/fa6a377b075c1abd29de951ced4d58d0e1c88ba9

That commit revises the GB_jitifyer_command function to disable the call to system(...) if the JIT is disabled. I also changed the building of the JITpackage, to replace it with an empty stub if the JIT is disabled.

The PreJIT is still enabled with these changes. To use it, you'd need to build GraphBLAS for a computer that can run the entire JIT (say on the Mac), with the JIT enabled. Then try the end user application, copy the JIT kernels back into the GraphBLAS project:

cp ~/.SuiteSparse/GrB9.3.0/c//.c ~/mystuff/SuiteSparse/GraphBLAS/PreJIT

then rebuild the GraphBLAS library, with GRAPHBLAS_USE_JIT=OFF, and cross-compile for iOS.

DrTimothyAldenDavis commented 3 weeks ago

Here's an example:

(1) build GraphBLAS on the Mac (not iPad) with the JIT enabled and run the gauss_demo and other demos. You should see about 33 kernels in your JIT cache:

$ ls */*.c
0f/GB_jit__AxB_dot3__03fe100eee2eee55__wildadd_wildmult.c
13/GB_jit__apply_unop__0000db0dbe__fx64_cmplx_real.c
16/GB_jit__trans_unop__0802ee0ee5__gauss.c
19/GB_jit__apply_bind1st__0000eee0efec1__addgauss.c
1b/GB_jit__user_op__0__addgauss.c
21/GB_jit__apply_unop__00006e06ef__realgauss.c
21/GB_jit__AxB_saxpy3__03fe100eee0eee45__wildadd_wildmult.c
3c/GB_jit__apply_unop__07fe8ee8ef__ijgauss.c
3d/GB_jit__trans_unop__0802ee0eef__gauss.c
40/GB_jit__AxB_saxbit__03fe100eee0eee8a__mycx_plus_mycx_times.c
49/GB_jit__trans_unop__08006e06ef__realgauss.c
56/GB_jit__AxB_saxpy5__03fe500eee0eeecd__addgauss_multgauss.c
63/GB_jit__AxB_saxpy4__03fe300eee0eeec7__addgauss_multgauss.c
66/GB_jit__subassign_22__1000eee0eec8__addgauss.c
68/GB_jit__AxB_saxbit__03fe100eee0eee8a__addgauss_multgauss.c
6c/GB_jit__trans_unop__0802ee0ee5__wildtype.c
6f/GB_jit__apply_unop__0000eb0ebe__mycx_cmplx_imag.c
75/GB_jit__apply_unop__0000eb0ebe__mycx_cmplx_real.c
77/GB_jit__add__1002e0e0eee00__wildtype.c
9f/GB_jit__AxB_dot3__03fe100eee2eee55__addgauss_multgauss.c
a3/GB_jit__colscale__0100eee0eee45__multgauss.c
a8/GB_jit__rowscale__0100eee0eee45__multgauss.c
b2/GB_jit__apply_unop__0000db0dbe__fx64_cmplx_imag.c
b4/GB_jit__user_type__0__gauss.c
b7/GB_jit__reduce__03feee1__wildadd.c
c9/GB_jit__apply_bind2nd__0000eee0eefc4__multgauss.c
c9/GB_jit__AxB_dot4__03fe900eee0eeec5__addgauss_multgauss.c
cc/GB_jit__reduce__83feee2__addgauss.c
d1/GB_jit__subassign_22__1000eee0eec8__multgauss.c
d3/GB_jit__trans_bind1st__0000eee0efe41__multgauss.c
d3/GB_jit__trans_bind2nd__0000eee0eef44__multgauss.c
de/GB_jit__build__02eeeee__wildtype.c
ee/GB_jit__reduce__83feee3__addgauss.c

(2) copy the kernels you want into GraphBLAS/PreJIT. My source is in ~/dev2/SuiteSparse. I copied over every kernel for the "gauss" user-defined type and its operators:

$ cp */*gauss*c ~/dev2/SuiteSparse/GraphBLAS/PreJIT

(3) rebuild GraphBLAS but with the JIT disabled. cmake should report that the JIT is disabled, but it should also build the PreJIT kernels you selected:

-- GraphBLAS CPU JIT: disabled (any PreJIT kernels will still be enabled)
...
-- Creating an empty GraphBLAS/JITpackage (JIT disabled):
...
-- ------------------------------------------------------------------------
-- CMAKE report for: GraphBLAS
-- ------------------------------------------------------------------------
-- inside common SuiteSparse root:  true
-- install in SuiteSparse/lib and SuiteSparse/include: 1
-- build type:           Release
-- BUILD_SHARED_LIBS:    ON
-- BUILD_STATIC_LIBS:    OFF
-- C compiler:           /usr/bin/cc 
-- C flags:               -Wundef  -std=c11 -lm -Wno-pragmas  -fexcess-precision=fast  -fcx-limited-range  -fno-math-errno  -fwrapv  -O3 -DNDEBUG
-- C Flags release:      -O3 -DNDEBUG 
-- compile definitions:  NJIT
-- ------------------------------------------------------------------------
-- Configuring done (0.7s)
-- Generating done (0.5s)
-- Build files have been written to: /home/faculty/d/davis/dev2/SuiteSparse/GraphBLAS/build
gmake[1]: Entering directory '/home/faculty/d/davis/dev2/SuiteSparse/GraphBLAS/build'
[  0%] Building C object CMakeFiles/GraphBLAS.dir/JITpackage/GB_JITpackage.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/Config/GB_prejit.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__AxB_dot3__03fe100eee2eee55__addgauss_multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__AxB_dot4__03fe900eee0eeec5__addgauss_multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__AxB_saxbit__03fe100eee0eee8a__addgauss_multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__AxB_saxpy4__03fe300eee0eeec7__addgauss_multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__AxB_saxpy5__03fe500eee0eeecd__addgauss_multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__apply_bind1st__0000eee0efec1__addgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__apply_bind2nd__0000eee0eefc4__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__apply_unop__00006e06ef__realgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__apply_unop__07fe8ee8ef__ijgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__colscale__0100eee0eee45__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__reduce__83feee2__addgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__reduce__83feee3__addgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__rowscale__0100eee0eee45__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__subassign_22__1000eee0eec8__addgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__subassign_22__1000eee0eec8__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__trans_bind1st__0000eee0efe41__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__trans_bind2nd__0000eee0eef44__multgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__trans_unop__08006e06ef__realgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__trans_unop__0802ee0ee5__gauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__trans_unop__0802ee0eef__gauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__user_op__0__addgauss.c.o
[  0%] Building C object CMakeFiles/GraphBLAS.dir/PreJIT/GB_jit__user_type__0__gauss.c.o
...

You may need to also do an install since otherwise the old libgraphblas will be used with the JIT enabled. Now if you run ./build/gauss_demo with the rebuilt libgraphblas, you should see 'prejit' in its output "burble". If you delete your JIT cache (~/.SuiteSparse/GrB9.3.0) and run this program, you'll see that I don't compile any JIT kernels, but the gauss_demo still uses the PreJIT kernels.

$ ./build/gauss_demo | grep jit

gauss_demo:
jit: status 2
 [ GxB_Type_new (prejit: ok) 
jit: status 2
 [ GxB_BinaryOp_new (prejit: ok) 
jit: status 2
 [ GrB_reduce (A bitmap) (prejit: ok) 
 [ GrB_mxm C=A*B, saxpy (B = B*B, anz: 15 bnz: 15) (bitmap saxpy) (prejit: ok) (bitmap to full) 
 [ GrB_reduce (A full) (prejit: ok) 
 [ GrB_mxm (iso mask: struct) (iso wait:M 0 zombies, 4 pending) (iso build) (hyper to sparse) C<M>=A'*B, masked_dot_product (dot3) (S{S} = Sf'*Sf) nthreads 1 ntasks 1 (prejit: ok) (sparse to bitmap) 
 [ GrB_mxm C=A*B, colscale (Sf=Sf*S) (prejit: ok) 
 [ GrB_mxm C=A*B, rowscale (Sf=S*Sf) (prejit: ok) 
 [ GrB_mxm C=A'*B, dot_product (dot4: F += Sf'*Sf) (prejit: ok) (C in place) 
 [ GrB_mxm C=A*B, saxpy (saxpy4: F += Sf*F) (coarse, threads: 1) (prejit: ok) (C in place) 
 [ GrB_mxm C=A*B, saxpy (saxpy5: F += F*Sf) (prejit: ok) (C in place) 
 [ GrB_apply (shallow-op) (prejit: ok) 
 [ GrB_apply (shallow-op) (prejit: ok) 
 [ GrB_apply (transpose-op) (transpose) (1-thread bucket transpose) (prejit: ok) (full to sparse) 
 [ GrB_apply (transpose-op) (transpose) (1-thread bucket transpose) (prejit: ok) (full to sparse) 
 [ GrB_apply (shallow-op) (prejit: ok) 
 [ GrB_apply (transpose-op) (transpose) (bitmap/full transpose) (prejit: ok) 
 [ GrB_apply (shallow-op) (prejit: ok) 
 [ GrB_transpose (transpose) (bitmap/full transpose) (prejit: ok) 
 [ GxB_Matrix_concat (sparse concat) (transpose) (bitmap/full transpose) (transpose) (transpose) (1-thread bucket transpose) (prejit: ok) (transpose) (1-thread bucket transpose) (transpose) (transpose) (bitmap/full transpose) 
 [ GrB_assign (pending: 0) Method 22: (C full) += scalar (prejit: ok) 
 [ GrB_assign (pending: 0) Method 22: (C full) += scalar (prejit: ok) 
gauss_demo: all tests pass

I had to revise the gauss_demo program to get this to work, only because it had some intentional "bad" JIT kernels. I had those as an example of what happens if a JIT kernel fails to compile. However, this attempt also disables the corresponding good PreJIT kernel, so it's not a good test when the runtime JIT is disable but PreJIT kernels are in place. I revised the gauss_demo program accordingly, so it's a better example of the PreJIT usage.

sbelbin commented 3 weeks ago

Thank you for your report.

IIUC, you'd like to cross-compile GraphBLAS on macOS for iOS. I don't know much about development for iOS. But you might need to follow the notes for cross-compilation here: https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/13806726cbf470914d012d132a85aea1aff9ee77/GraphBLAS/JITpackage/README.md#cross-compilation

Which errors exactly do you see when you are trying to build with -DGRAPHBLAS_USE_JIT=OFF (before you manually defined NJIT)?

I've done what you've asked. It compiles the GraphBLAS/Source/GB_jitifyer.c and since the iOS doesn't provide the system results in a failure to compile. See a segment of the build messages below.

In file included from /Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_jitifyer.c:10: In file included from /Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB.h:56: /Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_cuda_gateway.h:64:20: warning: implicit conversion loses integer precision: 'int64_t' (aka 'long long') to 'int' [-Wshorten-64-to-32] int gpu_hack = GB_Global_hack_get (2) ;


/Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_jitifyer.c:476:42: warning: passing 'char *[5]' to parameter of type 'const char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]
        (void) dl_query (&hash, version, ignored, NULL, NULL, 0, 0) ;
                                         ^~~~~~~
/Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_jitifyer.c:1410:42: warning: passing 'char *[5]' to parameter of type 'const char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]
    bool ok = dl_query (&hash2, version, library_defn, id, term, zsize, tsize) ;
                                         ^~~~~~~~~~~~
/Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_jitifyer.c:2268:18: error: 'system' is unavailable: not available on iOS
    int result = system (command) ;
                 ^
DrTimothyAldenDavis commented 3 weeks ago

/Users/sbelbin/tmp/SuiteSparse/GraphBLAS/Source/GB_jitifyer.c:2268:18: error: 'system' is unavailable: not available on iOS int result = system (command) ; ^

Got it. The latest commit to the dev2 branch should fix that error. If NJIT is defined, then I never call GB_jitifyer_command anyway.

sbelbin commented 3 weeks ago

I appreciate the speedy replies and response.

Regarding the commit code changes, I think that it could be refined it so that the GB_jitifyer.c andsome of it's peers aren't compiled rather than making GB_jitifyer_command function into a no-op. But, I'd need a cycle to try an idea to see what that would be. When I figure something, I get back with a response as a PR.

With regards of this issue, I would state that there is a viable fix with the commit that you've applied in dev2 branch.

On separate matter but relates to JIT in general and making system calls.

There are platforms and contexts where invoking system is restricted, requires an privilege escalation, run in a isolated sandbox (such as edge servers), devices such as Apple iPad devices & web/cloud applications using Web-Assembly + WASI. Our team is considering the latter so that our solution can running as part of a cloud-application.

As you've stated in other replies of this thread, the benefits of JIT provides computational performance gains. The challenge is doing in a secure manner is a challenge, since code injection is part of threat vector.

However, IMHO that is separate problem than my reported issue of disabling JIT issue.

mmuetzel commented 3 weeks ago

Thank you for showing the results. So, the error with unusable system occurs on compilation.

The PR #836 should be setting a reasonable default for GRAPHBLAS_USE_JIT if system cannot be used. If a value for that variable is already set in the cache, a message or error will be emitted (depending on how strict the *_USE_* variables should be handled).

DrTimothyAldenDavis commented 3 weeks ago

Regarding the commit code changes, I think that it could be refined it so that the GB_jitifyer.c andsome of it's peers aren't compiled rather than making GB_jitifyer_command function into a no-op. But, I'd need a cycle to try an idea to see what that would be. When I figure something, I get back with a response as a PR.

The GB_jitifyer.c methods are required to enable the PreJIT, which is in place even if NJIT is #defined and GRAPHBLAS_USE_JIT is OFF. So this would not be a good approach.

The current state of the code on the dev2 branch is what we want to do.

If the run time JIT is disabled, then system() isn't called and isn't compiled into GraphBLAS. GraphBLAS won't try to compile any JIT kernel at run time. Also, the executable that fails to build the JITpackage is no longer created or used either, so it doesn't need any code-signing. It's now replaced with a configure_file command in cmake to create an empty JITpackage. The GB_JITpackage.c file contains the compressed source files of GraphBLAS itself, which it needs for the run-time JIT, but these files are not needed if the run-time JIT is disabled, and they are not needed by the PreJIT kernels either:

https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/7e1a123cc46689956e9f6af6e9eb1cd072f43116/GraphBLAS/CMakeLists.txt#L258-L273

So I think we've resolved this as far as we can. The Apple iPad will never be able to use the run-time JIT (no compiler, and no system() command). But the PreJIT could still be used, if the end user application were run on a Mac, let's say, and the JIT was enabled there to create kernels that would then be later copied into GraphBLAS/PreJIT, as PreJIT kernels. Then the revised GraphBLAS would be cross-compiled for the iPad, with the new baked-in PreJIT kernels. Those would work just fine on the iPad.

I'm not suggesting that you have to use PreJIT kernels. But they would work if you'd like to exploit that feature.